Changelog

GitHub

Hver væsentlig ændring, udgivelse for udgivelse. Samme fil findes i repository'et og er oversat til alle 19 sprog.

[1.231.4] — 2026-09-07

Rettet — v1.231.3 rettede eftervirkningen af Doctor-klikket, ikke øjeblikket. Meldt igen, fra mobil og fra skrivebord.

Rettet

withSpinner omskrev stadig knappen, mens forespørgslen var undervejs. v1.231.3 fik den til at gemme barnenoderne og gendanne dem i finally, og de kom tilbage — men travlhedssignalet kørte stadig replaceChildren med teksten '⏳ ' + original. I hele doctor.mjs-kørslen indeholdt 36 px-kvadratet derfor ⏳ 🩺Doctor og blev til en bred pille, der brød rækken; på skrivebordet så det ud som et sammenklemt ⏳🩺Doctor. En knap med elementbørn omskrives nu slet ikke: dens signal er klassen .is-loading, som nu bytter ikonet ud med et timeglas i CSS, så geometrien ikke kan ændre sig: 36 px i hvile, 36 px undervejs, 36 px bagefter.

Noter

Lektionen handler om assertionen, ikke om koden. Porten fra v1.231.3 ventede på, at aria-busy forsvandt, og målte først derefter — den kunne per konstruktion kun se den tilstand, finally allerede havde repareret. Det nye tjek holder selv løftet åbent og måler midt i flugten. 3012 → 3013 test.

[1.231.3] — 2026-09-07

Rettet — et klik på Doctor ødelagde den øverste bjælke på mobil. Meldt fra en telefon samme dag som v1.231.2 udkom.

Rettet

UI.withSpinner fladede børnene ud i den knap, den var ved at dekorere. Dens travlhedssignal gik gennem textContent: gem button.textContent, skriv '⏳ ' + original, skriv tilbage. At tildele textContent erstatter alle børn med ét tekstnode — og v1.231.2 havde netop delt hver handling i den øverste bjælke op i .btn-ico + .btn-label med etiketten skjult under max-width: 900px. Første tryk på Doctor ødelagde derfor begge <span> for altid: mobilreglerne havde intet tilbage at ramme, etiketten kom tilbage som bar tekst, og 36 px-kvadratet voksede til en 🩺Doctor-pille, der lagde sig oven på temaskifteren. Det helede ikke af sig selv — kun en genindlæsning gendannede opmærkningen. Rettelsen gemmer barnenoderne og gendanner dem med replaceChildren; rene tekstknapper, altså de fleste af de 24 kaldsteder, opfører sig præcis som før.

  • FIND-3 — søgefeltet var faldet sammen til 8 px på en 320 px-telefon. Da bjælken kom på én række, stod searchbaren tilbage som det eneste fleksible element, og sidste changelog sagde det ligeud: »må skrumpe til ingenting«. Den skrumpede til ingenting: 8 px felt ved 320 px, 28 px ved 340 px — ét tegn af en pladsholder på 21. Klikbar og skrivbar, men ikke længere læselig som felt. Ingen min-width klarer det: ved 320 px bærer bjælken 32 px polstring, en 40 px-menu og 162 px handlinger, uden 120 px at give. Derfor gemmer feltet sig under 420 px bag et forstørrelsesglas og folder sig ud over hele bjælken ved tryk: 182 px ved 320 px, 222 px ved 360 px, 252 px ved 390 px, uden overløb ved nogen bredde. Knappen beholder ét tilgængeligt navn og melder tilstand via aria-expanded, og 🔍/✕-skiftet er ren CSS. Over 420 px ændrer intet sig. Fundet af et browser-regressionsgennemløb mod live-builden.

Noter

Det er samme fejlklasse som applyI18n()-fælden noteret i v1.231.2 — kode der tildeler textContent til et element, som nu har elementbørn — nået via en anden kalder. Lektionen generaliserer: at dele et elements indhold op i barne-<span> gør enhver eksisterende textContent-skriver på det element til en latent fejl. Låst to gange: node:vm over den ægte withSpinner og et klik i en rigtig browser ved 320 px. Begge bekræftet at fejle mod den gamle kode. 3009 → 3012 test.

[1.231.2] — 2026-09-06

Rettet — den mobile topbjælke brød om på to rækker, serveren kørte et ældre forældreprojekt, og cvstart.ru-omdirigeringen gav 404 for enhver sti, der allerede nævnte et sprog.

Rettet

  • Den mobile topbjælke er igen én række, med handlinger som rene ikoner. Handlingsknapperne blev tvunget ned på en anden række i fuld bredde: en telefon viste [☰ · søg] over [🔔 🌙 Doctor Åbn Scan] — to brede piller på deres egen linje. Nu er de 36 px kvadrater (🩺 / ⚡) ved siden af klokken og temaskifteren, og alt er på én række ved 320 px. Målt, ikke skønnet: dokumentbredden svarer til viewporten ved 320, 360, 390 og 430 px og i hele båndet 560–760 px, hvor knapperne før overlappede søgefeltet. Sproget påvirker ikke længere det mobile layout, fordi etiketten er skjult og knappen et fast kvadrat; over 900 px vender etiketterne uændret tilbage.
  • Serveren kørte forældreprojekt 1.31.0, selv om udgivelsen var bygget mod 1.32.0. /api/health på produktionsserveren meldte parentVersion: 1.31.0. 95 kørselsfiler synkroniseret, to fjernet. Fundet af browser-QA på den live flade.
  • cvstart.ru satte /ru/ foran enhver sti uden at se på, hvad der allerede stod der. /ru/help blev til /ru/ru/help og /en/help til /ru/en/help; begge 404. Det første får man ved at kopiere en URL fra hovedsiden; det andet lukkede engelsktalende besøgende helt ude fra den engelske udgave. En sti, der allerede nævner et af de 16 sprogpræfikser, går nu uændret igennem, en fjernes (engelsk ligger i roden), og resten får stadig /ru/.

Ændret

  • 98 forældede QA-prompts flyttet til qa/archive/superseded-prompts/. qa/README.md har siden v1.137.0 dokumenteret, at kun den aktuelle udgivelses prompt ligger øverst — reglen blev ikke anvendt i 95 udgivelser.
  • Yderligere fem prompts forlod øverste niveau — de kaldte sig aktuelle uden at være det. REGRESSION-FINAL.md kaldte sig selv »den ene autoritative, versionsuafhængige regressionsprompt«, men dens §§11–15 er fem lukkede cyklusprotokoller (v1.55.x → v1.59.7), og dens angivne hjælpe-baseline lød 28 H2 / 103 H3 på 16 sprog mod 32 / 122 og 17 i dag: en QA-agent, der fulgte den, ville være faldet på §9 ved første skridt. QA-REGRESSION-PROMPT.md bar et navn uden version og indhold fra v1.226.0. QA-REGRESSION-PROMPT-v1.76.0-FULL.md var fastlåst 155 udgivelser tilbage, REGRESSION-PROMPT-FINAL.md lukker cyklussen v1.58.52 → v1.59.10, og QA-FULL-REGRESSION.md duplikerede dem alle på et v1.131.1-grundlag. Med dem fulgte PARENT-SYNC-WORKLIST-v1.26.0.md (forældreprojektet er nu på 1.32.0), og den daterede UX-AUDIT-2026-07-06.md flyttede til reports/. Fire drivere bliver tilbage, med egne baselines opdateret til de faktiske v1.231.2-tal. qa/README.md er skrevet om, så den beskriver den mappe, der findes.

Noter

  • To specificitetsfælder er nu kommenteret i app.css: desktopreglerne er erklæret længere nede end max-width: 900px-blokken, så ved samme specificitet vinder de — den mobile gap blev stille stående på 24 px (hvilket løb 320 px over), og ikonet forblev skjult (tomme firkantede knapper).
  • applyI18n() tildeler el.textContent, så i18n-nøglen flyttede til et indre <span>; på knappen ville den slette ikonet ved hvert sprogskifte.
  • Forældreprojektets første rsync afbrød midt i overførslen på en fil, der ikke længere findes lokalt, og meldte alligevel succes. Forælder-deploys verificeres nu med kontrolsum, aldrig med exit-kode.

[1.231.1] — 2026-09-06

Rettet — tællergennemløbet fra v1.231.0 omskrev kontonavnet i alle links.

Rettet

  • Hvert Fighter90-link blev til Fighter92. Kildetæller-gennemløbet i v1.231.0 erstattede 90 med 92 under en cifergrænse, der korrekt springer 290 og 901 over, men rammer 90 inde i Fighter90. 562 links i alle 17 README’er, alle 17 hjælpepakker og sidens hjælpespejle, plus 138 i wikien, pegede på en konto, der ikke findes. Opdaget af en bruger — på det manglende billede.
  • Fem historiske udgivelseshenvisninger forskubbede sig. 85 → 87-gennemløbet gjorde v1.85.0 til v1.87.0 og opfandt dermed en udgivelse, der aldrig blev skåret.

Noter

  • En cifergrænse er ikke nok: den beskytter et tal mod nabocifre, ikke mod at være del af en identifikator eller en versionsstreng. Tællerne selv er rigtige: 92 kilder, 87 EN-adaptere, 3009 tests.
  • Forældrerepositoriet blev ikke berørt.

[1.231.0] — 2026-09-05

Tilføjet — to scanningskilder fra forældreprojektets career-ops v1.32.0 (Collage, Telegram streng), Gems REST-tilstand og en defekt, som porteringen bragte frem i forælderens egen kode.

Tilføjet

  • To nye kilder, 90 → 92 (87 EN + 5 RU), ALL_ADAPTERS 85 → 87. Begge uden token.
    • Collage (provider: collage) — Collage HR’s offentlige jobside-API. Stisegmentet er den adresse, lejeren selv valgte, ikke et slug fra firmanavnet: den læses fra api: eller fra en secure.collage.co/jobs/<adresse>-URL og gættes aldrig — en gættet adresse ville scanne en andens board.
    • Telegram (streng) (provider: telegram-channel) — læser de samme t.me/s/<kanal>-forhåndsvisninger som den eksisterende kilde telegram, men laver den modsatte byttehandel: Et opslag bliver kun en række, når det nævner en arbejdsgiver OG linker til en opslagsside. Digests, opslag med skjult arbejdsgiver og rene kontaktopslag frasorteres. Lav dækning med vilje — opstrøms måltes 32-77 % af opslagene som beståede — men hver række bærer en rigtig arbejdsgiver og et rigtigt link. Begge leveres, som hos forælderen.
  • Gem fik en valgfri REST-tilstand ved siden af GraphQL-vejen (api: https://api.gem.com/job_board/v0/<board>/job_posts). Den udledes aldrig af et board-id, og GraphQL-vejen forbliver standarden. Porteret fra #3783.

Rettet

  • Stedfilteret i telegram-channel kunne ikke se kyrillisk og udnævnte byer til arbejdsgivere. Forælderens LOCATIONISH_RE brugte \b, en ren ASCII-ordgrænse, der aldrig udløses ved siden af kyrillisk: alle de russiske alternativer var uopnåelige, og Senior Engineer | Москва returnerede “Москва” som arbejdsgiver. Præcis den feltforveksling, hele tilskrivningspolitikken findes for at forhindre, og den ramte udbyderens primære publikum. web-ui-porteringen bruger Unicode-tjek, det samme som forælderen allerede gør en konstant længere nede i ROLE_WORD_RE. Fastholdt af en test, der fejler på ASCII-formen. Endnu ikke rettet opstrøms.

Noter

  • Forælderens Workday-facetgendannelse (#3851, #3874) krævede ingen portering — web-ui paginerer slet ikke Workday, én POST ved offset: 0.
  • providers/_types.js ændrede sig kun i dokumentationen.
  • Tests: 2962 → 3009 (+47).

[1.230.0] — 2026-09-05

Ændret — tre udbyderrettelser fra forældreprojektets career-ops v1.32.0 samt én defekt, som selve porteringen bragte frem.

Tilføjet

  • Welcome to the Jungle tager et Algolia-filters-udtryk, der anvendes på serveren (wttj: { filters: "offices.country_code:FR AND contract_type:full_time" }). Et nøgleord alene indsnævrer ikke et globalt board: Det er Algolias relevansrangering og ikke scannerens filtre, der afgør, hvilke max_hits resultater der kommer tilbage — vores kører først bagefter, på det allerede modtagne, så alt ud over loftet er usynligt, uanset hvor godt det passer. Et filter formindsker selve mængden i stedet for at omrangere den, og loftet pr. forespørgsel stiger derfor fra 200 til 1000. Med et filter bliver queries valgfrit: Den tomme forespørgsel betyder “alt, der passerer filteret”. Porteret fra forældreprojektet #3757.

Rettet

  • Radancy advarer ikke længere “truncated”, når en lejer blot leverer færre opslag, end dens eget banner påstår. Forældreprojektet holdt data-total-results op mod ni rigtige lejere: Fem passede, men fire — en lille og en meget stor — leverede 10-56 % færre unikke opslag end annonceret, uden en eneste dubletrække. Banneret overdriver, hvad lejerens eget søgeindeks faktisk serverer, så en sammenligning med den akkumulerede optælling gav falsk alarm på flertallet af boards. Advarslen udløses nu kun, når vores eget max_jobs/max_pages stoppede gennemløbet — det eneste tilfælde, kalderen kan handle på; totalResults bliver i beskeden som kontekst og afgør aldrig noget. Porteret fra #3839.
  • Radancy omgår cachen ved hver JSON-fragmentforespørgsel. Et cachelag foran den rute gentager forældede svar hos nogle lejere: Det samme opslag dukker op igen flere sider senere, mens et andet aldrig serveres — reproduceret ni ud af ni gange opstrøms. Cache-Control/Pragma-headere ændrede intet; en tilfældig parameter pr. forespørgsel løste det. Den skal være unik pr. kald, aldrig afledt af sidetallet: En deterministisk parameter ville stadig give cachen en stabil nøgle og dermed den samme stabile, forkerte afbildning. Porteret fra #3839.
  • Greenhouses kontorlister har deterministisk orden. Greenhouse lover ikke rækkefølgen af offices[] mellem svar, og mængden hentet fra /offices-træet følger sin gennemløbsorden. Begge ender i opslagets location-felt, så et board, der omrokerede sine kontorer, omskrev den streng — og et uændret opslag blev læst som nyt. Forældreprojektet rettede mængden (#3839); web-ui havde en anden forekomst af samme defekt, som ikke findes der — offices[0]-tilbagefaldet, der bruges, når et opslag ikke selv bærer en placering — og begge sorteres nu.

Noter

  • Forældreprojektets iCIMS-rettelse (#3728) krævede ingen portering. Den læser hver jobLocation-post fra en detaljesides JSON-LD, fordi nogle lejere udsender en helt UNAVAILABLE post før den rigtige adresse. web-uis iCIMS tager placeringen fra listesidens HTML og åbner aldrig en detaljeside.
  • Ændringen i _http.mjs krævede ingen portering. Den udtrækker isRefusedRedirectError til en anden forbruger, som web-ui ikke har; adfærden i isRetryableError er uændret.
  • Den placeringsbevidste deduplikering (#3751) spejles ikke — den bor i scan.mjs-pipelinen i forælderens CLI.
  • Registret uændret: 90 kilder (85 EN + 5 RU). Tests: 2956 → 2962 (+6).

[1.229.0] — 2026-09-03

Tilføjet — fire scanningskilder fra forældreprojektet career-ops v1.31.0: Built In, Feishu Jobs, Garena og MokaHR.

Tilføjet

  • Fire nye kilder, 86 → 90 (85 EN + 5 RU), ALL_ADAPTERS 81 → 85, alle uden tokens. Built In dækker de ni markeder på den amerikanske tech-tavle og har ingen standardforespørgsel: en post uden queries: og categories: scanner intet og siger det — en delt kilde må ikke bære nogens søgeord; et marked uden for listen afvises, aldrig stille erstattet af den nationale tavle. Feishu Jobs accepterer præcis to værtsformer, som bruger forskellige stier til jobsiden. Garena er ét firma: office former linket, ikke listen. MokaHR returnerer et krypteret svar (AES-128-CBC-konvolut med nøglen ved siden af) — sløring, ikke sikkerhed, men uden dekryptering læses intet.

Rettet

  • htmlToText kunne lade en ufuldstændig tag-åbner slippe ud i teksten. safe &lt;img src=x onerror=1 kom ud som safe <img src=x onerror=1. Nu følges hver afkodning af en oprydning, og den afsluttende åbner mister sin vinkelparentes. Porteret fra forældreprojektet (#3491).

Noter

  • Intet blev porteret fra forældreprojektets Workday-rettelse. Den redder tenants, hvis backend låser pagineringen ved offset 2000 — web-ui paginerer slet ikke Workday (ét POST på offset: 0, 100 rækker).
  • Rettelserne i verify-cv-facts og merge-tracker krævede ingen portering: web-ui kører de scripts fra forældreprojektets checkout.
  • Tests: 2909 → 2956 (+47).

[1.228.5] — 2026-08-30

Rettet — den rapporterede version beskrev filen på disken, ikke den kørende kode.

Rettet

  • /api/health genlæste package.json ved hver forespørgsel, så en forældet proces rapporterede en version, den ikke kørte. QA fandt en lokal instans, der svarede version: 1.228.4 og samtidig gav 404 for /api/ping — en rute tilføjet i 1.228.3: startet før udrulningen, serverede den gamle kode og rapporterede den nye fils version. Sådan ser en udrulning ud, der kopierer filer og aldrig genstarter: den ene streng, en operatør tjekker, er den, der ikke kan se problemet. Samme klasse som symlinket fra v1.228.1, hvor rsync afbrød midt i overførslen og alligevel meldte succes.

    Versionen fanges nu ved modulets indlæsning og beskriver dermed den kørende kode. En forældet proces rapporterer den gamle version — sandheden, synlig med det samme. parentVersion læses fortsat per forespørgsel: den beskriver forældreprojektets checkout, som denne proces ikke indlæser, og som legitimt kan ændre sig under en kørende server.

[1.228.4] — 2026-08-30

Rettet — den uautentificerede livstegnssonde lavede diskarbejde ved hver forespørgsel.

Rettet

  • GET /api/ping læste og parsede package.json ved hvert kald. Det er det eneste endpoint, der kan nås uden legitimationsoplysninger, så en disklæsning plus en JSON-parsning per forespørgsel er en denial-of-service-håndtag rakt til hvem som helst — CodeQL markerede det som manglende ratebegrænsning. Versionen læses nu én gang ved ruteregistreringen; den kan alligevel ikke ændre sig uden en genstart, så handleren laver slet ingen I/O. Ratebegrænsning ville have sat loft over skaden; at fjerne arbejdet fjerner håndtaget.
  • Maskeringen af profilejerens rigtige navn uden for loopback er nu fastholdt af en test. /api/health erstattede det allerede med hidden — men kun fordi den række deler hidden ?? value-vagten med projektroden. Intet testede det, så en ændring, der gav rækken sin egen værdi, ville have lækket et rigtigt menneskes navn til LAN’et uden at noget opdagede det.

[1.228.3] — 2026-08-30

Fixed — the docs assistant could not answer in English, Telegram company names arrived truncated, and a monitor had no way to see the service was up.

Fixed

  • The docs assistant answered “no matching help sections were found” in English while the same question worked in Russian. Retrieval was fine; the context builder was not. buildAskPrompt did if (ctx.length + sec.body.length > MAX_CONTEXT) break — a break, so one oversized section ended the loop and left the context empty, and the assistant truthfully reported it had nothing. The English §5 had grown to 16 081 bytes against a 14 336-byte budget (partly because v1.228.0 added telegram_channels to it); the Russian §5 was 13 009 and fit. Same ranking in both languages — §5 was first — only the size differed.

    Two changes: a section past 6 KB is now split at its ### boundaries, so telegram_channels is its own retrievable chunk (1 340 bytes) that ranks first in both languages; and an oversized section is skipped or truncated rather than ending the loop. The guide went from 32 chunks to 75.

  • A Telegram company label yielded the sentence after it, not the name. Компания: FinCore Technology (продуктовая разработка, высоконагруженные системы) became FinCore Technology (продуктовая разработка, высоконагруженны — capped at 60 characters, cut mid-word. Three of 141 rows. The name now ends at the first separator that introduces a description — a spaced dash (so Coca-Cola survives), a comma, semicolon, pipe or opening parenthesis — and any remaining cap falls on a word boundary. This source attributes a company as fact; a truncated sentence is as wrong as a guessed name, only less obviously so.

Added

  • GET /api/ping — a liveness probe that leaks nothing. { ok, version } and no more. /api/health reports absolute paths, the profile owner’s real name and which API keys are set: legitimate for an authenticated operator, never for the public internet. A monitor behind a Basic-auth gate previously had no way to see the service was up at all.

[1.228.2] — 2026-08-30

Fixed — a two-word search in /api/scan-results matched the phrase, not the words, and under-reported badly.

Fixed

  • ?q= now matches every term independently instead of the literal phrase. The query was a single includes(q) over title + company + location, so продакт менеджер found only rows carrying those two words in that exact adjacency — 32 of the 162 that carry both. Менеджер продукта and Менеджер по развитию продукта were invisible to it: the same words, reordered or with filler between them.

    This is how a narrow match becomes a wrong answer. The Telegram assistant asked for all Продуктовый менеджер reported 9 — faithfully, because 9 was what the endpoint said. The count it quoted was honest; the endpoint’s was not. Word order and the words between are not something a person typing two words intended to pin.

    Matching is AND across terms, so widening precision costs nothing: a row must still carry every term. менеджер разработчик returns zero rather than the union.

[1.228.1] — 2026-08-29

Fixed — a dangling symlink in the repo that silently truncated deploys.

Fixed

  • .claude/skills/refero-design was a tracked symlink to a path that has never existed here. It pointed at ../../.agents/skills/refero-design, which resolves to .agents/ at the repo root; there is no such directory, and the link arrived in the v1.118.0 parity pack from a machine where the surrounding folders nested differently. Anyone cloning the repo has been getting a broken link ever since.

    It was not inert. rsync aborts on it mid-transfer — a deploy today reported success while the server kept running the previous version, and the mismatch only surfaced because the version was checked afterwards. The parent project’s node test-all.mjs also crashes outright when a web-ui checkout sits inside its tree, because its fixture copy walks the working directory and cannot stat the link. Nothing referenced it: the only refero matches in the repo are the Polish word preferowany.

[1.228.0] — 2026-08-29

Tilføjet — Telegram-kanaler som scanningskilde og en pagineret forespørgselstilstand på /api/scan-results.

Tilføjet

  • Telegram-kanaler er nu en skanbar kilde. En telegram_channels:-blok i portals.yml lister dem; hver læses fra den offentlige forhåndsvisning https://t.me/s/<kanal>. Register: 85 → 86 kilder (81 EN + 5 RU), ALL_ADAPTERS 80 → 81. Telegram udgiver ingen RSS, og Bot-API’et kan ikke læse en kanal, botten ikke administrerer — begge oplagte veje er lukkede. /s/-visningen er almindelig serverrenderet HTML: uden login, uden JS, uden cookie. Efterprøvet på 16 kanaler: 15 gav 20 opslag hver på et bart GET.
  • GET /api/scan-results har fået en pagineret forespørgselstilstand. ?q=<tekst>&limit=50[&region=ru|en][&set=filtered|fresh][&offset=N] returnerer { total, returned, offset, limit, set, rows }, hvor total er antallet FØR paginering. Uden parametre returnerer ruten stadig hele snapshottet — #/scan-tabellen afhænger af den form.

Rettet

  • Telegram-assistenten svarede ud fra en brøkdel af data. Dens skill pegede allerede på /api/scan-results, men ruten kunne kun returnere hele snapshottet — omkring 2 MB — hvilket ikke er i en agents kontekst. På „find alle Product Managers“ meldte den 9 træffere, hvor snapshottet havde hundredvis, og sagde, at den „arbejdede med et begrænset lokalt indeks“. Det var sandt: den kunne se endpointet, men ikke fordøje det. Med paginering koster samme spørgsmål 2 KB og giver et ærligt total. Skillen blev også skrevet om: den bad om at opsummere de nye opslag, altså fresh frem for filtered.

Noter

  • Et kanalopslag er prosa, ikke en jobpost. Ingen strukturerede felter: titlen tages fra første indholdsmæssige linje, firma/sted/løn fra udtrykkelige etiketter. At skille rigtige opslag fra reklamer og digests overlades til det eksisterende title_filter — det samme, der allerede er indstillet for andre kilder. Det er spor, ikke en liste.
  • Firmaet gættes aldrig. Uden etiket tilskrives rækken kanalen (@rabotaphp): en forkert arbejdsgiver ender i trackeren som en kendsgerning.
  • En tom parsning er en fejl, ikke „ingen stillinger“. t.me svarer med en omdirigering for en privat eller manglende kanal; nul rækker ville læses som en stille dag og skjule en tastefejl i konfigurationen for altid. jobGeeks gør præcis dette (HTTP 302) og er bevidst ikke konfigureret.
  • Fjernarbejdsdetektion bruger en Unicode-ordgrænse i stedet for \b, der kun kender ASCII — samme fælde som titelfilteret i v1.227.3, her fanget af en test før udgivelse.
  • 15 kanaler konfigureret og verificeret live: 299 opslag, 15/15 kanaler. 30 nye tests. Tests: 2865 → 2895.
  • The README test counts jumped by hundreds, and no, this release did not add them. The localized READMEs carried unit-test totals frozen at 1856 / 1945 / 1955 / 549 / 419 / 284 / 2527 depending on the file — each stale since a different release, and several contradicting the badge at the top of the same page. They now all read 2895, verified by running the suite rather than by copying a badge. Playwright (70 / 90 / 12 → 101), e2e smoke (20 → 21), route modules (12 / 32 → 37), smoke flows (12 → 22) and the test-file count (218 → 329) were stale in the same way. The Total row also repeated the unit count, so it under-summed the three suites below it; it now reads the real sum (3040).

[1.227.5] — 2026-08-29

Rettet — den regionale scanning brugte serverens hukommelse op, og en Playwright-suite fejlede på sin egen nedtagning.

Rettet

  • Den regionale scanning slog serveren ihjel med OOM. ru-scanner samlede alle rå hits fra alle forespørgsler og deduplikerede og filtrerede først til sidst. Forespørgselslisten består bevidst af nærsynonymer (Golang, Go разработчик, Golang разработчик, Senior Go…), så det samme opslag kommer igen én gang pr. forespørgsel, og arrayet holdt et multiplum af det unikke antal — inklusive beskrivelserne, som udgør hovedparten af et jobobjekt og som filtrene alligevel kasserer næsten alle. Målt: 742 MB heap på en rigtig kørsel med 21 forespørgsler. Serveren begrænser Nodes heap til 490 MB (V8 udmåler den efter maskinens 956 MB RAM), så scanningen væltede tjenesten med FATAL ERROR: Reached heap limit — fire gange på én dag. Deduplikering og filtrering sker nu pr. forespørgsel, hvilket bragte samme kørsel ned på 177 MB, 76% mindre. De rapporterede tal er uændrede: det unikke total bæres af et Set af URL-strenge.
  • net::ERR_SOCKET_NOT_CONNECTED fik CI til at fejle tilfældigt. Tre Playwright-suiter kalder window.stop() for at standse igangværende requests, før de hævder, at ingen konsolfejl opstod. Chromium rapporterer den ene bevidste handling under tre navne afhængigt af socketens tilstand: ERR_ABORTED ved annullering, ERR_EMPTY_RESPONSE undervejs og ERR_SOCKET_NOT_CONNECTED, når socketen allerede var væk. Det fælles filter kendte kun de to første. Det dukkede op i locale-gennemgangen i tr, mens playwright-forms og playwright-smoke var én uheldig kørsel fra det samme.

Noter

  • Hvorfor først nu. Listen voksede fra 14 til 21 forespørgsler, da product manager-søgninger kom til. Den gamle implementerings hukommelse skalerede med det samlede antal hits, så +50% forespørgsler sprængte maskinens loft.
  • Dedup-ændringen bevarer adfærden, og det er testet, ikke påstået. tests/ru-scanner-dedup-order.test.mjs fastholder den akavede retning — et senere dublet, der IKKE består filtrene, skal fortrænge et tidligere, der bestod — og kører 200 randomiserede ækvivalenstjek mod den gamle implementering.
  • Konsolfilteret forbliver smalt. Kun familien af annullerede requests er benign; afvist forbindelse, DNS-fejl, reset, enhver 5xx og ufangede JS-undtagelser vælter fortsat assertionen.
  • To hypoteser blev afprøvet og forkastet i stedet for sendt: en Caddy-timeout (konfigurationen er ren, flush_interval -1 er korrekt til SSE) og Nodes 5-minutters standard-requestTimeout (en nedskaleret reproduktion viste, at den ikke afbryder et langt streaming-svar). Det egentlige bevis var Reached heap limit i journalen. Tests: 2860 → 2865.

[1.227.4] — 2026-08-29

Rettet — word: / stem: blev stadig ignoreret af content_filter; v1.227.3 rettede kun titelfilteret.

Rettet

  • content_filter respekterede ikke præfikserne. v1.227.3 lærte title_filter moderprojektets word: / stem:-præfikser, men lod content_filter blive ved sit eget rå lower.includes(k), så en præfikset post dér stadig blev matchet som den bogstavelige tekst "word:java" — den samme tavse no-op, ét filter længere fremme. content_filter læser jobbets BESKRIVELSE, og standarden har altid været en simpel delstreng: derfor afviser et bart negativt java alt, der blot nævner „JavaScript“; præfikset er måden at undtage én post fra det. Moderprojektets compileContentKeyword er porteret: samme præfiks-maskineri, men bevidst uden automatisk forankring af korte nøgleord — titelfilteret forankrer 2–3-bogstavsforkortelser, fordi „COO“ inde i „Coordinator“ altid er forkert, mens en kort sekvens midt i et afsnit prosa rutinemæssigt er tilsigtet (aws, gcp, sql, go).

Noter

  • Fundet i AI-gennemgangen af v1.227.3-PR’en, som bemærkede, at koden ikke dækkede det, dens egen kommentar påstod — der stod „title_filter / content_filter“, mens kun titelstien var koblet på. Kommentaren skelner nu udtrykkeligt: begge filtre respekterer præfikserne, kun titelfilteret forankrer forkortelser.
  • Ligeledes verificeret ud fra den gennemgang og uændret: at flytte 2–3-bogstavsreglen fra \b til Unicode-grænsen opfører sig identisk for ASCII og er kun strengere, hvor det skal være — COO_lead og coo1 bevares fortsat (understreg og ciffer er ordtegn i begge), Coordinator bevares, „Директор COO“ og „VP «Продукт»“ kasseres korrekt. 14 grænsetilfælde kontrolleret.
  • Upræfiksede content_filter-poster beholder deres hidtidige matchning byte for byte, en tom eller manglende beskrivelse passerer stadig, og et tomt word: / stem: matcher intet i stedet for alt. 6 nye tilfælde i tests/content-filter.test.mjs. Tests: 2852 → 2858.

[1.227.3] — 2026-08-29

Rettet — titelfilterets word: / stem:-præfikser blev ignoreret i stilhed, så de filterlinjer intet gjorde.

Rettet

  • web-ui implementerede ikke moderprojektets word: / stem:-præfikser. title_filter (og content_filter) matcher som standard delstrenge uden hensyn til store/små bogstaver — derfor afviser et bart negativt intern også „International Product Manager“ og „Internal Tools Engineer“. I stedet for at vende den standard — et brud for enhver konfigureret installation — gjorde moderprojektet præcision valgfri pr. post: word:intern matcher kun hele ordet, og stem:agent skal starte et ord og må fortsætte (og adskiller „Agentforce“ fra „Reagents“). web-ui havde ingen af delene og matchede posten som den bogstavelige tekst "word:intern", som ikke findes i nogen jobtitel. Linjen blev en tavs no-op: den samme portals.yml filtrerede korrekt via CLI’en og slet ikke her, så hvert ekskluderet praktikopslag nåede alligevel #/scan-tabellen. Porteret fra moderprojektets title-keywords.mjs, inklusive den Unicode-bevidste ordgrænse (\p{L}\p{M}\p{N}_) i stedet for \b, der kun kender ASCII og ramte midt i ord i titler med accenter eller kyrillisk.

Noter

  • Fundet under gennemgang af en rigtig portals.yml, som netop havde taget word:intern i brug netop for at et bart intern holdt op med at kassere „International Product Manager“. Præfikset virkede i CLI’en; web-ui beholdt stiltiende alle praktikopslag. Adfærden er nu identisk.
  • Standarderne er uændrede. Et nøgleord uden præfiks beholder sin hidtidige matchning: delstreng for fraser og alt med ikke-bogstaver (.NET, SAP , L&D), ordgrænse-forankring for 2–3-bogstavsforkortelser. Et tomt word: / stem: betragtes som en tastefejl og matcher intet — som negativ ville et tomt mønster matche enhver titel og vælte en hel scanning på grund af et forvildet kolon.
  • Reglen for 2–3-bogstavsforkortelser bruger nu samme Unicode-grænse: før \b, hvorfor coo og word:coo var uenige om ikke-ASCII-titler — to stavemåder af én regel.
  • 6 nye tilfælde i tests/title-filter.test.mjs. Tests: 2846 → 2852.

[1.227.2] — 2026-08-29

Rettet — #/config scrollede sidelæns på smalle telefoner.

Rettet

  • MOBILE-1: #/config flød vandret over på viewports ≤ 352 px. Hvert select-felt bar et inline min-width: 300px. En inline-stil slår stylesheetet, så kontrollen kunne ikke krympe med sin container: ved 320 px viewport landede selectens højre kant på 353 px, siden fik en vandret scrollbar, og kontroller blev skubbet ud over højre kant. Ramte alle 18 udbyder-/modelselects (cfg-llm-provider og hver cfg-*-model). Nu min-width: min(300px, 100%) + max-width: 100%, så de behagelige 300 px kun gælder, når der er plads. Enheder på eller under tærsklen: iPhone SE (1. gen., 320 px), ældre Android, Galaxy Folds ydre skærm.

Noter

  • Hvorfor alle tidligere mobilgennemgange missede det. 360 px og 375 px har lige akkurat slæk nok til at skjule overløbet, og Playwright-suiterne kører i et 1280 px bredt vindue. Intet i CI havde nogensinde målt et viewport smallere end 375 px. Den nye tests/playwright-narrow-viewport.mjs gennemgår de formularbærende ruter ved 320 px og fejler ved ethvert vandret overløb med det bredeste element nævnt i beskeden; et andet tilfælde fastholder, at ingen #/config-select rækker ud over viewportet. Det blev først verificeret, at den reproducerede fejlen (scrollWidth 353 > clientWidth 320, 18 selects med højre kant 353). Playwright: 99 → 101.
  • Kendt og bevidst endnu ikke afskærmet: 280 px (Galaxy Folds ydre skærm) flyder stadig over med ~5 px, men af en anden årsag — langt indhold i konfigurationskortets <details>-blokke og den 256 px brede sidebar mod et 280 px viewport, ikke det inline min-width, denne udgivelse retter. At ombryde ved en bredde, ingen udbredt telefon melder, er separat arbejde; suitens WIDTHS-liste er klar til det.
  • Også rettet: QA-prompten fra v1.227.1 kaldte opfølgningsruten #/modes/followup. Mode-sider registrerer det bare slug (Router.register(cfg.slug)), så ruten er #/followup, og #/modes/followup giver korrekt 404. Kun dokumentation.
  • Unit-suiten uændret på 2846 (den nye dækning er på browserniveau).

[1.227.1] — 2026-08-29

Rettet — kildeopdelingen i hjælpen stemte ikke med sig selv, og GitHub-banneret blev printet som rå markup i appen.

Rettet

  • §17 angav en total og en opdeling, der ikke gik op. Alle hjælpebundter sagde „server/lib/sources/-registret leverer 85 adaptere — 78 engelske + 5 russiske“. 78 + 5 = 83, ikke 85; i ja/ko var afvigelsen nået til 77 (= 82). Hver ny kilde hævede totalen og lod leddet stå, så de to tal havde ligget og glidt fra hinanden gennem flere udgivelser. Opdelingen er nu 80 EN + 5 RU i alle 17 sprog. Det betyder mere end kosmetik: docs/help/<lang>.md er det ENESTE korpus, „Ask the docs“ bygger på, så den der spurgte om antallet af kilder, fik to modstridende tal ud af én sætning.
  • Samme sætning fastholdt et forældet versionsanker. „Pr. v1.213.0 leverer registret …“ overlevede i 16 sprog, mens tælleren flyttede sig to gange (83 i v1.219.0, 85 i v1.226.0). Ankeret var allerede repareret i hånden i v1.210.1 og gled simpelthen igen. Det er fjernet til fordel for en versionsfri formulering — selve tællingen holdes op mod det levende register, som ikke kan blive forældet.
  • Udbyder-banneret blev printet som escapet markup øverst i #/help. v1.225.0/v1.225.1 noterede, at det blev „fjernet i appen af UI.md() (ingen billedunderstøttelse)“. Det blander to ting sammen: UI.md() escaper først — den escaper hver byte af kilden før enhver markdown-transformation, hvilket er den rigtige XSS-grænse, men det modsatte af at fjerne. Ingen fjernede banneret, fordi ingen forsøgte, og alle 17 sprog åbnede #/help med 268 tegn ordret <p align="center"><img src="https://…. En ny fælles indgang (server/lib/help-markdown.mjs::stripGithubOnlyBlocks) kasserer ved læsning fritstående HTML-billedblokke — både for GET /api/help/:lang og for docs-assistantens korpus. Filerne beholder banneret, så GitHub viser stadig udstillingen.
  • Kolonnen „#“ på kadencetavlen har været tom siden v1.117.0. Den læste entry.appNum, men followup-cadence.mjs udsender num — appNum har aldrig eksisteret i payloaden. Nu læses begge. „Next up“-linjen fra v1.227.0 arvede samme fejl og rettes med.

Noter

  • Alle fire slap forbi, fordi intet vogtede dem. Hjælpens gates (canonical-docs-coverage, help-ui, help-ru-config-section) tæller OVERSKRIFTER — 32 H2 / 121 H3 — og ingen test havde nogensinde læst et tal inde i et afsnit eller set på, hvad hjælpe-indgangen faktisk serverer. To nye suiter lukker det: tests/help-source-counts.test.mjs (den angivne total er lig SOURCES.length; leddene svarer til den levende EN/RU-fordeling og summer til totalen; afsnittet fastlåser ingen version) og tests/help-banner-strip.test.mjs (banneret bliver på disken til GitHub, overlever aldrig filtreringen, første renderede linje i hvert bundt er dets overskrift, filtreringen forbliver smal, og begge forbrugere går igennem den). Begge blev verificeret røde mod netop disse fejl før commit. Testsuite: 2837 → 2846.
  • Ingen ændring i register, scanner eller rute-kontrakter; kilder er fortsat 85 (80 EN + 5 RU), ALL_ADAPTERS 80.

[1.227.0] — 2026-08-28

Tilføjet — SEEK Hongkong (JobsDB), et kun-forfaldne-filter på opfølgninger, og fortrolige arbejdsgivere viser nu det bureau, der formidlede dem.

Tilføjet

  • JobsDB Hongkong via den eksisterende Jobstreet/SEEK-kilde. Hongkong kører under JobsDB-brandet, men står på den samme SEEK-platform bag det samme v5-endpoint, så den behøver ingen selvstændig kilde — kun hk.jobsdb.com på værtslisten og siteKey: HK-Main. Registret er uændret: 85 kilder (80 EN + 5 RU) og ALL_ADAPTERS 80 — dette er et nyt MARKED på en eksisterende adapter, ikke en ny adapter.
  • Kun-forfaldne-filter på kadencetavlen (#/modes/followup). Et nyt afkrydsningsfelt indsnævrer tavlen til det, der kan handles på lige nu. Forfald læses fra den urgency, moderprojektets followup-cadence.mjs allerede har beregnet (urgent / overdue) — aldrig fra trackerens status, som er applied/responded/interview og ikke ville matche noget. Når intet er forfaldent, navngiver tavlen den nærmeste planlagte opfølgning i stedet for at vise en tom tilstand. Logikken bor i det rene modul public/js/lib/followup-view.js, spejl af moderprojektets followup-view.mjs.
  • Fortrolige arbejdsgivere tilskrives det bureau, der formidlede dem. Et opslag med tilbageholdt arbejdsgiver registreres som ? i trackeren, og rekruttereren står i Via-kolonnen. #/tracker viste et bart ?, så flere fortrolige rækker var umulige at skelne, og logo-resolveren havde intet at matche på. En sådan række læses nu “Fortrolig · via <bureau>”, henter sit logo fra bureaunavnet og kan findes på det navn i søgefeltet. Kun præsentation — det kanoniske company-felt overskrives aldrig med rekruttereren. Nyt rent modul public/js/lib/company-presentation.js, spejl af moderprojektets company-presentation.mjs.

Rettet

  • Jobstreet/SEEK kaldte et udgået endpoint. Kilden pegede stadig på chalice-search v4 (/api/chalice-search/v4/search), som SEEK har pensioneret; moderprojektet migrerede til /api/jobsearch/v5/search, og web-ui fulgte aldrig med. Nu forespørger enhver Jobstreet/SEEK-post v5. v5-elementets form læses indfødt (job-URL bygget ud fra id, locations[0].label, advertiser.description, salaryLabel), den v4-specifikke projektionsparameter solrFields er væk, og en post, hvis portals.yml stadig fastholder den døde v4-sti, beholder sit markedsværtsnavn, mens stien genopbygges på v5 — uden brugerredigering.

Noter

  • career-ops 1.30.0-paritet (moderprojektets HEAD 8d64f65 → 6cc46a4; dets VERSION viser stadig 1.30.0 — release-please halter efter main). Ikke porteret, med begrundelser: iCIMS JSON-LD-stedudfyldning — web-ui’s iCIMS-kilde har slet ingen enrichDate()-hook (kun listesider), så der er ingen kodesti at rette; ikke-fatal CLI-stderr (#1974) — web-ui’s runner afgør fejl alene ud fra exit-koden og har aldrig haft den heuristik; Turbopack-stisporing — web-ui har ingen bundler; cv-sync-check-rettelser — videresendes skrivebeskyttet og fail-soft; Playwright-sekvensering i scan.mjs, Block H-svar, updater/doctor/update-system-værn, den rekursive syntakskontrol, Go-dashboardet og de tilføjede jd-skill-gap/verify-cv-facts-selvtests — rene CLI-flader, som web-ui ikke kalder, eller selvtests uden adfærdsændring. Testsuite: 2818 → 2837.

[1.226.0] — 2026-08-27

Tilføjet — to vietnamesiske jobkilder: ITviec og CareerViet.

Tilføjet

  • ITviec + CareerViet (Vietnam). To host-fastlåste vietnamesiske boards tilslutter sig scanneren via provider: itviec / provider: careerviet-poster: ITviec (itviec.com, tech) og CareerViet (careerviet.vn, bred dækning). Begge er token-fri HTML-scrapere med SSRF-host-pin, kun-HTTPS, fail-soft pr. virksomhed og sideloft. Registret rummer nu 85 kilder (80 EN + 5 RU), ALL_ADAPTERS 80 — begge vises i #/scan-kildefilteret.

Noter

  • Paritet med career-ops 1.30.0 (parentVersion 1.29.0 → 1.30.0). Ikke porteret (kun CLI/community eller allerede dækket): Hired Wall, /calibrate, clean-markers, skabelonpakker, doctor, pdf/LaTeX og eval/tracker/scan-CLI’erne som web-ui ikke kalder; _html-to-text-rettelsen og roleFuzzyMatch fandtes allerede; title-filter stem:-præfikset er udskudt. Testsuite: 2818.

[1.225.1] — 2026-08-27

Rettet — udbyderlogo-banneret vises nu i README og hjælpen.

Rettet

  • Banneret fra v1.225.0 blev ikke vist på GitHub: den selvstændige images/providers.svg havde en ugyldig font-family (indlejrede dobbelte anførselstegn), som GitHub afviser, <img> brugte en repo-relativ src (rå HTML <img> opløser ikke relative stier på GitHub), og <p>-blokken manglede en afsluttende tom linje. Den peger nu på en gengivet images/providers.png via en absolut URL, med tom-linje-adskillelse; SVG’en er også rettet til gyldig XML.

Noter

  • Kun docs; ingen kode- eller testændring. cvstart.org-udstillingen og appens felter var allerede korrekte (indlejret SVG, ikke denne fil). 2784

[1.225.0] — 2026-08-27

Tilføjet — et udbyderlogo-banner i README og hjælpeguiden.

Tilføjet

  • Udbyderlogo-banner. En enkelt selvstændig images/providers.svg — de 18 LLM-udbydere, med det rigtige mærkelogo (simple-icons, CC0) for de 11, der udgiver et, og et monogram i mærkefarven for de 7 øvrige — står nu øverst i README (×17) og den indbyggede hjælpeguide. (Appen tegner selv felterne med det rigtige logo; banneret vises på GitHub og fjernes i appen af den XSS-sikre renderer.)

Noter

  • Kun docs — ingen kode- eller testændring; SVG’en er indlejret (ingen fjernressource). Scanningskilder uændret: 83. Testsuite: 2784.

[1.224.0] — 2026-08-26

Ændret — LLM-udbyderfliserne viser nu rigtige mærkelogoer.

Ændret

  • Rigtige udbyderlogoer. Udbyderfliserne — API-nøglefelter i Indstillinger, Forbrugs-rækkerne, dashboard-chippen, “Aktiv”-oversigten i Indstillinger, ⚡ eval-resultatet og velkomstbanneret — viser nu det rigtige mærkelogo for de 11 udbydere, der udgiver et open source-ikon (Anthropic · Gemini · OpenAI · Qwen · OpenRouter · GitHub · DeepSeek · Kimi · MiniMax · Mistral · Ollama; enkelt-sti-SVG’er fra simple-icons, CC0). De 7 uden et udgivet ikon (Hermes · GLM/Z.ai · Grok · Together · Fireworks · BytePlus Ark · Volcengine Ark) beholder monogrammet i mærkefarven. Stadig CSP-sikkert af konstruktion: logo-stien er en indlejret statisk konstant — ingen fjernressource, ingen innerHTML.

Noter

  • Ingen rute- eller adfærdsændring; samme ProviderLogo.el(slug)-API. provider-logo.js voksede (de indlejrede logo-stier). Scanningskilder uændret: 83. Testsuite: 2784.

[1.223.0] — 2026-08-26

Rettet — en vellykket ⚡ live-vurdering blev malet som en fejl; installer desuden OpenWorker-coworkeren direkte fra dens GitHub-URL eller .zip.

Rettet

  • Farve på ⚡ vurderings-badge. En vellykket live-vurdering farves ikke længere som en fejl. In-process-udbyderne (OpenRouter, DeepSeek, …) returnerer ingen subproces-code, så den strikte code === 0 var falsk, og enhver succes blev rød (mens der stod “exit 0”). Farven følger nu resultatet — kun en subproces, der afslutter med en kode forskellig fra 0, farves rød; et kodeløst live-resultat er badge-ok, og “· exit N”-suffikset vises kun ved en rigtig exit-kode.

Ændret

  • Installer OpenWorker-coworkeren fra dens GitHub-URL / .zip. Coworkerens dokumentation beskriver nu én-kommandos-installeren (curl … | bash, idempotent — genbruger et eksisterende career-ops / web-ui) og de tre installationsveje i OpenWorker (GitHub-URL · .zip · enkeltfil-import) i docs/integrations/openworker.md, in-app-hjælp §32 (×17) og README.

Noter

  • Lukkede et gammelt dækningshul: Recruitee-kilden har nu en ende-til-ende-test af v1.214.2’s citerede vinkel-rettelse (et > i en tag-attribut må ikke lække ind i beskrivelsen). Scanningskilder uændret: 83. Testsuite: 2783.

[1.222.0] — 2026-08-26

Ændret — feltteksterne for de udvidede udbydere (DeepSeek … Volcengine Ark) er nu lokaliseret på alle 17 sprog.

Ændret

  • Lokaliserede udbyder-felttekster. Hver config.<slug>Hint for de 11 OpenAI-kompatible udbydere tilføjet i v1.216.0–v1.217.0 (DeepSeek · GLM/Z.ai · Kimi · MiniMax · Mistral · Grok · Together · Fireworks · Ollama · BytePlus Ark · Volcengine Ark) — API-nøgle-, model- og base-URL-teksterne under Indstillinger → API-nøgler — er nu oversat på alle 17 sprog i stedet for at falde tilbage til engelsk. Tilmeldings-URL’er, model-id’er og ⚡ live-eval-markøren bevares ordret.

Noter

  • Ingen adfærdsændring — den engelske hintFallback i field-specs.js beskytter stadig en manglende nøgle, og en ny kontrakttest bekræfter, at hver hintKey i feltbeskrivelserne kan slås op på alle 17 sprog. Scanningskilder uændret: 83. Testsuite: 2779.

[1.221.0] — 2026-08-26

Sikkerhed — forsvar i dybden mod DNS-rebinding på scannerens fetch-sti.

Sikkerhed

  • Scannerens HTTP-kerne (fetchJson / fetchText i server/lib/http-json.mjs) slår nu hver kildes host op på den rigtige netværkssti og nægter at forbinde, hvis den slår op til en privat, loopback, link-local, CGNAT eller cloud-metadata-adresse — og lukker en DNS-rebinding-vektor. Scannerens hosts er allerede pinnet til offentlige domæner, så det er forsvar i dybden; bruger-URL-stien havde allerede stærkere forbindelses-pinning (safe-fetch.mjs). Vagten kører kun på den rigtige fetch-transport — en injiceret test-fetchImpl slås aldrig op.

Noter

  • Ingen adfærdsændring for en sund scanning. Scanningskilder uændret: 83. Tests: 2775.

[1.220.0] — 2026-08-26

Tilføjet — scan flere Get on Board-kategorier fra én post.

Tilføjet

  • En getonbrd-post kan nu angive categories: [programming, operations-management, machine-learning-ai] (eller en enkelt category:) i stedet for kun programming-feedet; opslag dedupликeres pr. URL på tværs af kategorier, med et loft på 12. Eksisterende poster er identiske (standard er stadig programming).

Noter

  • Kun server; SSRF-host-pinningen (www.getonbrd.com) og redirect:'error' er uændrede, og en ugyldig kategori-slug afvises før nogen forespørgsel. Scanningskilder uændret: 83. Tests: 2771.

[1.219.0] — 2026-08-26

Tilføjet — Torre slutter sig til scanneren, og nu er hver udbyder-etiket korrekt.

Tilføjet

  • Torre (provider: torre) — torre.ai’s pan-latinamerikanske talentmarked, en offentlig søgning uden godkendelse med fjernstillinger, der ikke når Greenhouse/Lever/Ashby; én afgrænset forespørgsel pr. post. Registret har nu 83 kilder (78 engelske + 5 russiske). Desuden monogram for den aktive udbyder på velkomstbanneret.

Rettet

  • a16z Speedrun-scanningen stoppede for tidligt på et board, der roterer (en kort side midt i gennemløbet blev opfattet som den sidste og afkortede til 149 af ~300); den stoler nu på feedets total_pages. Og velkomstbanneret udledte udbyderen fra et kort med 4 poster (viste den rå slug for de øvrige 14) — det bruger nu etiket+monogram fra de 18; udbyder-noten i Indstillinger går fra 7 til 18.

Noter

  • Get on Boards nye valgmulighed med flere kategorier pr. post er ikke koblet på her endnu (kræver en refaktor på kildeniveau). Tests: 2768.

[1.218.0] — 2026-08-26

Tilføjet — udbyder-badges (og korrekte navne) overalt, hvor en udbyder vises.

Tilføjet

  • Udbyder-monogrammer på dashboard-chippen, “Aktiv”-oversigten i Indstillinger og ⚡ evalueringsresultatets overskrift.

Rettet

  • Forældede etiketter: tre skærme udledte navnet fra et 5-punkts-kort (evalueringsresultatet mærkede enhver ikke-Anthropic-udbyder som “Gemini”); de bruger nu ProviderStatus.label (18). Nøgletællingen viste “/ 7” → 18. LLM_PROVIDER-tippets slug-liste fik ark / arkcn på alle 17 sprog.

Noter

  • Kun klient, CSP-sikker. Ingen serverændring. Scanningskilder: 82. Tests: 2758.

[1.217.1] — 2026-08-26

Teststyrkelse — endpoint-dækning for hele udbyderkataloget.

Tilføjet

  • En parametriseret run<Provider>-test, der tjekker endpoint, standardmodel og Bearer-godkendelse for Kimi, MiniMax, Mistral og Fireworks.

[1.217.0] — 2026-08-26

Tilføjet — Ark slutter sig til LLM-listen (18 udbydere). BytePlus Ark og Volcengine Ark — ByteDances Doubao-modeller — er nu ⚡ live-udbydere via samme OpenAI-kompatible kerne og en basis-URL pr. region.

Tilføjet

  • BytePlus Ark (ARK_API_KEY, international) og Volcengine Ark (ARK_CN_API_KEY, Kina) — OpenAI-kompatibel Chat Completions via runOpenAICompatible(). Angiv ARK_MODEL / ARK_CN_MODEL (et Doubao-modelnavn eller dit ep-… endpoint-id); ARK_BASE_URL / ARK_CN_BASE_URL skifter region. Begge føjes til auto-rækkefølgen (til sidst), med deres monogram i Indstillinger og Forbrug. Web-UI’et dækker nu 18 udbydere live.

Noter

  • Samme betroede konfiguration + http(s)-skematjek som resten (aldrig SSRF-validatoren for job-URL’er). Scanningskilder uændret: 82. Tests: 2755.

[1.216.0] — 2026-08-26

Tilføjet — ni LLM-udbydere mere, hver med sit eget brand-felt. Dine ⚡ live-evalueringer kan nu køre via DeepSeek, GLM (Z.ai), Kimi (Moonshot), MiniMax, Mistral, Grok (xAI), Together, Fireworks eller en helt lokal Ollama — én nøgle væk, hver markeret med et monogram ved siden af sit felt i Indstillinger.

Tilføjet

  • Ni OpenAI-kompatible udbydere. DeepSeek, GLM (Z.ai), Kimi (Moonshot), MiniMax, Mistral, Grok (xAI), Together AI, Fireworks AI og Ollama (helt lokal, ingen nøgle). Angiv en nøgle — eller OLLAMA_BASE_URL for Ollama — i Indstillinger, så føjes den til auto-rækkefølgen efter Hermes; fastgør en hvilken som helst med LLM_PROVIDER. Together hoster også Thinking Machines’ Inkling (thinkingmachines/Inkling). Web-UI’et dækker nu 16 udbydere live.
  • Udbyder-monogrammer. Et CSP-sikkert initial-felt i brandets farve markerer hver udbyder ved siden af dens nøglefelt i Indstillinger og i dens række på Forbrug-siden — inline SVG, ingen eksterne logoer, intet forlader din maskine.

Noter

  • Udbydernes basis-URL’er er betroet konfiguration, der går gennem runOpenAICompatible() med et http(s)-skematjek (Ollamas loopback er tilladt), aldrig SSRF-validatoren for job-URL’er. Scanningskilder uændret: 82. Tests: 2752.

[1.215.0] — 2026-08-26

Tilføjet — kør hele din jobsøgning fra OpenWorker. En ny coworker driver denne pipeline fra Andrew Ngs open source AI-coworker-app, og hjælpen i appen dækker den nu, så Spørg dokumentationen-assistenten kan guide dig.

Tilføjet

  • OpenWorker-coworker. En kodefri OpenWorker-coworker — Fighter90/career-ops-coworker — kører hele jobsøgningen (scan, scoring, tilpasning, sporing, opfølgning) og kan starte dette dashboard, alt fra dit skrivebord. Det er en enkeltfils-persona leveret på 17 sprog, verificeret som installerbar med OpenWorkers egen loader.
  • Hjælp §32 “Run it from OpenWorker” (alle 17 sprog) dokumenterer den, så den indbyggede Spørg dokumentationen-assistent og den flydende hjælpeknap kan besvare spørgsmål om den. Også linket fra landingssidens footer, README, wikien og docs/integrations/openworker.md.

Noter

  • Kun dokumentation + site — ingen ændring af app-kode. Scanningskilder uændret på 82. Testsuite: 2742.

[1.214.2] — 2026-08-25

Rettet — den delte HTML→tekst-pipeline (Greenhouse / Recruitee-beskrivelser) lækker ikke længere tag-attributter ind i beskrivelsen, når en attributværdi indeholder et >-tegn.

Rettet

  • HTML-beskrivelser med > inde i en attribut strippes rent. Tag-strippen bag Greenhouse- og Recruitee-beskrivelserne brugte et naivt match, der stoppede ved det første >, så et tag som <a title="salary > 100k"> efterlod den efterfølgende attributtekst (100k">) i beskrivelsen. Den respekterer nu citerede attributværdier (enkelte eller dobbelte), stripper markup før afkodning af entiteter (så et kodet citationstegn i en attribut ikke bliver en falsk afgrænser), og bevarer stadig et bogstaveligt <> i ren tekst.

Noter

  • Testsuite: 2742. Scanningskilder uændret på 82. Intet andet nyt fra forælderen denne runde: de øvrige ændringer relayes skrivebeskyttet (follow-up / weekly-digest / rejection-latency / salary-gap-rettelser kræver ingen web-ui-ændring) eller er ikke web-ui-flader (et eksternt X/Xquik BYO-key-plugin, CLI/verify-rettelser). De valgfrie punkter — SmartRecruiters-detaljebeskrivelser, detect-reposts-aggregator-spring, stem: / word:-titelpræfikser, DNS-rebinding-hærdning — er stadig i kø.

[1.214.1] — 2026-08-25

Rettet — Ashby-beskrivelser er nu begrænset til samme længde som Greenhouse og Recruitee, så et indholdsfilter opfører sig ens på alle tre boards, og ét board kan ikke oppuste scan-cachen.

Rettet

  • Ashby-beskrivelser overholder nu samme længdegrænse som de andre boards. v1.214.0 fodrede Ashbys opslagstekst til indholdsfilteret, men — i modsætning til Greenhouse og Recruitee, der begrænser til 4000 tegn — blev Ashbys mappet direkte uden grænse (nogle 4× længere). Så det samme content_filter-ord kunne matche på Ashby men ikke Greenhouse alene afhængigt af, hvor det faldt i teksten, og ét board kunne tilføje hundredvis af KB til scan-cachen, som #/scan indlæser. Ashby begrænses nu til de samme 4000 tegn (dens tekst er allerede ren, så den afkortes, aldrig tag-strippet).

Noter

  • Testsuite: 2738. Scanningskilder uændret på 82.

[1.214.0] — 2026-08-25

Rettet — jobbeskrivelser fra Greenhouse, Ashby og Recruitee føder nu indholdsfilteret, så ord- / lande- / visumfiltre faktisk matcher de boards; og “Associate ” (inkl. akademiske rangeringer) fejlklassificeres ikke længere som entry-level.

Rettet

  • Indholdsfiltre virker nu på Greenhouse, Ashby og Recruitee. Disse boards bærer nu hvert opslags fulde tekst som dets beskrivelse, så et content_filter (eller et lande- / visum-ordfilter) matcher jobbets brødtekst i stedet for at lade boardet passere blindt. Ashby og Recruitee leverer brødteksten i deres liste-payload gratis; Greenhouse gjorde det allerede. Alle tre renses gennem én delt HTML→tekst-pipeline.
  • “Associate Director” / “Associate Professor” er senior, ikke entry-level. Senioritetsklassifikatoren (brugt af skip_tiers:) behandlede ordet “associate” som et entry-level-mærke, selv når det står foran en seniortitel. Den læser nu “Associate ” — inkl. akademiske rangeringer (Associate Professor, Associate Dean) — som senior, mens den holder ægte juniorvarianter (Associate Attorney, Associate Editor) som entry-level, og klassificerer stadig et ledende “Intern, Associate Dean” som en praktikplads.

Noter

  • Testsuite: 2736. Scanningskilder uændret på 82. Sat i kø til senere: valgfri SmartRecruiters-beskrivelsesberigelse (et detalje-kald pr. opslag), detect-reposts’ aggregator: true-board-spring, og de forankrede nøgleords-titelpræfikser stem: / word: — hver en valgfri konfiguration, ikke en ændring af standardadfærd. DNS-rebinding-hærdningen er stadig i kø til sin egen sikkerhedsudgivelse.

[1.213.0] — 2026-08-22

Tilføjet — MyCareersFuture, Singapores nationale jobbank, som scanningskilde. Rettet — Greenhouse-opslag bærer nu deres fulde tekst, så indholdsfiltre virker, og fjern-Ashby-roller skjules ikke længere bag en by-kun lokation.

Tilføjet

  • MyCareersFuture (Singapore) (mycareersfuture.gov.sg) — en ny token-fri scanningskilde for Singapores nationale offentlige jobbank, drevet af Workforce Singapore. Vælg den i Kilde-filteret på #/scan, eller tilføj en virksomhed med provider: mycareersfuture og en valgfri keywords-liste (falder tilbage til din profils målroller, som Job Bank). Læser det offentlige søge-API, host-fastlåst, uden nøgle.

Rettet

  • Greenhouse-opslag kan nu indholdsfiltreres. Greenhouse-boards hentes med opslagets fulde brødtekst, afkodet til ren tekst som opslagets beskrivelse — så et content_filter (eller et lande-/visum-ordfilter), der læser beskrivelsen, matcher nu faktisk Greenhouse-roller i stedet for at lade dem passere blindt.
  • Fjern-Ashby-roller droppes ikke længere af et byfilter. Ashby holder arbejdsmodellen (Remote/Hybrid/Onsite) adskilt fra kontorbyen, så en fuldt fjernrolle læstes stadig som f.eks. “San Francisco” — og et lokationsfilter, der blokerer den by, skjulte en rolle, du kunne tage. “Remote” tilføjes nu lokationen, når rollen er fjern, og workplaceType vinder over et forældet isRemote-flag, så en kontor-forankret hybridrolle ikke fejlmærkes.

Noter

  • Scanningskilder: 82 (77 engelske + 5 russiske). Testsuite: 2724. En DNS-rebinding-hærdning (validér en værts opløste adresse før forbindelse) er sat i kø til en dedikeret udgivelse — den kræver et web-ui-specifikt design frem for et direkte port.

[1.212.1] — 2026-08-21

Rettet — cvstart.org-landingssiden undertalte scannerens jobkilder (den viste 80 og udelod Job Bank (Canada)); den matcher nu appens 81 igen, og site-buildet fejler højlydt, hvis de to nogensinde er uenige.

Rettet

  • Landingssidens “Jobkilder”-tal er igen synkroniseret med appen. Efter v1.212.0 viste cvstart.org 80 boards og manglede den nye Job Bank (Canada)-chip, mens appen, scan-dropdownen og hjælpeguiden alle listede 81. Landingssiden bygger sin liste ved at indlæse det levende scanner-register, og én kilde kunne ikke indlæses i det build på grund af måden, den hentede en YAML-afhængighed på — så den blev stille droppet. Job Bank indlæser nu den afhængighed dovent, ligesom resten af appen gør ved scanningstid, så den vises altid.
  • Site-buildet nægter nu at udgive et uoverensstemmende kildeantal. Hvis registret nogensinde opremser færre kilder, end der findes på disken (signaturen på en kilde, der ikke kunne indlæses), fejler buildet med en klar besked i stedet for stille at udgive det forkerte tal.

Noter

  • Appens adfærd er uændret — scanneren havde altid alle 81 kilder; kun landingssiden var påvirket. Scanningskilder: 81 (76 engelske + 5 russiske) — uændret. Testsuite: 2687.

[1.212.0] — 2026-08-21

Tilføjet — Job Bank (Canada), det føderale nationale jobboard. Fjernet — EchoJobs (dets feed er nu bot-blokeret). Rettet — Consider-boards giver resultater igen, og Lever-opslag med flere lokationer skjuler ikke længere halvdelen af deres lokationer.

Tilføjet

  • Job Bank (Canada) (jobbank.gc.ca) — en ny token-fri scanningskilde for Canadas føderale nationale beskæftigelsestjeneste, et board med stort volumen som ingen aggregator dækker godt. Vælg den i Kilde-filteret på #/scan, eller tilføj en virksomhed med provider: jobbankca og en valgfri keywords-liste (falder tilbage til din profils målroller). Læser det offentlige ATOM-feed, host-fastlåst, uden nøgle.

Fjernet

  • EchoJobs — pensioneret. Dets offentlige feed er nu bag bot-beskyttelse og returnerer intet, så at beholde den spildte blot en scanningsplads.

Rettet

  • Consider-boards giver resultater igen. Consider kræver nu et anonymt håndtryk (et GET der sår en session-cookie + CSRF-token) før det accepterer søgningen; uden det blev anmodningen lydløst afvist, og boardet så tomt ud.
  • Lever-opslag med flere lokationer skjuler ikke længere halvdelen af deres lokationer. Lever lægger én primær by i location og resten i allLocations; kun at læse den primære fik et opslag åbent i Barcelona OG Montevideo til at se ud som kun-Barcelona (og blev fejlagtigt droppet af et lokationsfilter). Begge flettes nu.

Noter

  • Blidere tempo mellem sider (250 ms, op fra 150) på de paginerede boards, af høflighed over for single-host karrieresider. Scanningskilder: 81 (76 engelske + 5 russiske) — uændret (Job Bank ind, EchoJobs ud). Testsuite: 2685.

[1.211.0] — 2026-08-19

Tilføjet — Yourator, et taiwansk tech-jobboard. Rettet — accenttegns-entiteter i titler/firmanavne afkodes nu overalt, og en virksomhed med en accent i navnet flagges ikke længere fejlagtigt.

Tilføjet

  • Yourator (yourator.co) — en ny token-fri scanningskilde for det taiwanske tech- og digital-jobmarked. Vælg den i Kilde-filteret på #/scan, eller tilføj en virksomhed med provider: yourator. Den læser det offentlige JSON-API (ingen nøgle, ingen browser), gennemgår hver side af boardet og udsender hvert opslags rigtige arbejdsgiverlink (dets eget ATS) med sporingsparametre fjernet.

Rettet

  • Accenttegns-navneentiteter afkodes nu overalt. Den delte HTML-afkoder fik Latin-1-bogstaverne (&eacute; → é, &ccedil; → ç, …), så et europæisk board der skriver D&eacute;veloppeur eller Fran&ccedil;ais ikke længere efterlader den literal i en titel, trackeren eller et genereret dokument. (Store bogstaver forbliver store — &Eacute; er É, ikke é — og et opslag som &constructor; resolver nu til sig selv.)
  • En virksomhed med en accent i navnet flagges ikke længere fejlagtigt for at være på sit eget domæne. “Işık” foldes nu til “isik” og matcher isik.com.tr; “Société Générale” matcher societegenerale.com. Det gamle tjek slettede accenttegns-bogstaver i stedet for at folde dem til deres ASCII-basis.

Noter

  • Scanningskilder: 81 (76 engelske + 5 russiske). Testsuite: 2667.

[1.210.1] — 2026-08-19

Rettet — Habr Career-stillingstitler og firmanavne med “&” eller anførselstegn ankommer ikke længere forvansket.

Rettet

  • Habr Career-kilden afkoder nu HTML-entiteter i titlen og firmanavnet, før de sendes videre. De server-renderede kort ankommer escaped (“Changellenge >>”, “Demand Forecasting & Inventory Optimization”, “ООО "М-ТЕХ"”), så et uafkodet “&” faldt lydløst igennem dit eget “&”-titelfilter — præcis det symptom, den forrige udgivelse lukkede på fem andre boards — og firmanavne nåede forvansket frem til trackeren og rapporterne. Entitetsafkodning er nu komplet på alle seks berørte kilder.

Noter

  • Testsuite: 2644.

[1.210.0] — 2026-08-19

Tilføjet — Senjob, scannerens første afrikanske jobboard (Senegal); skarpere titelmatch på fem boards mere.

Tilføjet

  • Senjob (senjob.com) — en ny token-fri scanningskilde for Senegal, scannerens første afrikanske board. Vælg den i Kilde-filteret på #/scan, eller tilføj en virksomhed med provider: senjob. Den læser den offentlige liste over almindelig HTTP (ingen nøgle, ingen browser), fastlåser hver forespørgsel til senjob.com og — da den parser HTML — behandler en liste, der pludselig intet giver, som et ødelagt board (en synlig fejl) frem for et land uden job.

Rettet

  • Titler med “&” taber ikke længere job på fem boards — på beesite, Cornerstone (csod), Hacker News “Who is hiring”, Phenom og TKMS ankommer titler HTML-escaped, så et escaped “&” i en rolle som “R&D Engineer” faldt igennem dit eget “r&d”-nøgleord, og opslaget forsvandt lydløst (et “sales & marketing”-veto udløstes heller ikke). Titler — og Phenom-lokationer — afkodes nu før filtrering.

Noter

  • Scanningskilder: 80 (75 engelske + 5 russiske). Testsuite: 2643.

[1.209.0] — 2026-08-17

Tilføjet — hjælpen i appen dækker nu, hvordan man registrerer udfaldet af en ansøgning, og “Spørg dokumentationen” kan føre dig derhen.

Tilføjet

  • Trackerens hjælp (§11) fik et afsnit “Registrér et udfald” på alle 17 sprog, der gennemgår knappen Udfald: vælg, hvad der skete (afvist / tilbud / ansat / afslået / ghostet / gik videre til samtale), forhåndsvis, hvad den vil gøre, og registrér — hvilket noterer resultatet, arkiverer det CV og den ansøgning, du sendte, og synkroniserer rækkens Status for dig. Den flydende “Spørg dokumentationen”-assistent læser guiden, så den fører dig nu til den knap i stedet for kun at foreslå, at du redigerer Status i hånden.

Noter

  • Hver hjælpepakke er nu 31 H2 / 119 H3 (var 118); paritetsvagterne blev hævet. Kun dokumentation — ingen kode- eller adfærdsændring. Suite: 2625.

[1.208.2] — 2026-08-16

Rettet — på en telefon ligger notifikations- og temaknapperne ikke længere oven på søgefeltet.

Rettet

  • v1.208.1 stoppede topbjælkens knapper i at overlappe sideoverskriften, men på en smal — dog ikke smalleste — telefon, især på sprog med længere knaptekster, klemte hele bjælken sig stadig ned på én række, så 🔔- og 🌙-knapperne kunne lande oven på søgefeltet. Handlingsknapperne (notifikationer, tema, Diagnose, Åbn Scan) rykker nu altid ned på deres egen anden række i fuld bredde på en telefon, så søgefeltet er fuldt læsbart og intet overlapper.

Noter

  • På en telefon flytter topbjælkens handlingsknapper til en anden række i fuld bredde og fjerner det skrøbelige “næsten fulde række”-bånd, hvor layoutet fordelte den resterende negative plads som overlap. En Playwright-vagt gengiver nu den præcise udløser — et sprog med lange tekster på tværs af 565–640px-båndet — og bekræfter, at bjælkens knapper aldrig deler pixels. Suite: 2621.

[1.208.1] — 2026-08-16

Rettet — på en telefon overlapper topbjælkens knapper ikke længere siden.

Rettet

  • v1.208.0 ombrød topbjælkens handlingsknapper (Diagnose, Åbn Scan, notifikationer, tema) til en anden række på smalle skærme, men bjælken beholdt en fast højde, så den ombrudte række flød ud og lå oven på sideoverskriften. Bjælken vokser nu til at rumme sine rækker, og indholdet flyder nedenunder.

Noter

  • Bjælkens faste height blev til min-height, så den vokser med sit indhold i enhver bredde (desktop er uændret). En Playwright-vagt tjekker nu også, at bjælken ikke flyder ud over siden. Suite: 2621.

[1.208.0] — 2026-08-16

Rettet — appen passer nu på en telefonskærm: ingen sidelæns scrolling mere.

Rettet

  • På en smal skærm skred hele appen ud til siden — topbjælken, tabeller, hjælpeartikler og indstillingsfaner gik ud over højre kant. Nu passer hver side i enhver bredde: topbjælkens knapper ombrydes til en anden række, brede tabeller og kodeblokke ruller inde i deres egen boks, hjælpen stabler indholdsfortegnelsen over artiklen, rækker af knapper/faner ombrydes, og lange stier eller URL’er brydes i stedet for at strække siden.

Noter

  • Årsagen var den klassiske flex/grid min-width: auto-fælde plus et par uindpakkede brede elementer; rettet med min-width: 0 på grid-elementer, overflow-wrap på markdown/titler, en scrollbar markdown-tabel og stabling af hjælpe-griddet ved mobilbrudpunktet. En Playwright-vagt tjekker 0 vandret overløb ved 375 px på hovedruterne. tests/playwright-smoke.mjs. Suite: 2621.

[1.207.2] — 2026-08-16

Rettet — AI-planer og karriereorienteringsprofiler vises ikke længere som et råt kode-dump.

Rettet

  • Nogle modeller pakker hele svaret ind i et markdown … kodehegn. Når det skete, dukkede udviklingsplanen og orienteringsprofilen op som en monospaced kodeblok i stedet for et dokument med overskrifter og lister. Det omsluttende hegn fjernes nu — kun når det omslutter hele svaret og sproget udtrykkeligt er markdown/md, så et ægte python/js/``` uden sprog kode-svar er urørt.

Noter

  • Håndteret ét sted i det fælles LLM-oprydningstrin (cleanLlmMarkdown), så alle AI-ruter nyder godt af det, og indre kodeblokke i det indpakkede svar overlever. tests/llm-output.test.mjs (+3). Suite: 2621.

[1.207.1] — 2026-08-16

Rettet — landingssiden løber ikke længere ud til siden på små telefoner.

Rettet

  • På en smal telefon kunne hero-området — overskriften, introlinjen og installationsterminalen — blive klippet af i højre kant, fordi en lang installationskommando og layoutkolonnerne ikke krympede til skærmen. De passer nu i enhver bredde; installationskommandoen ruller inde i sin egen terminalboks.

Noter

  • Et ustabilt E2E-smoke-tjek, der kunne fejle på en forbigående ressource-404, er også gjort robust: det ignorerer nu godartet netværksstøj (favicon / forbindelse / mislykket ressource) som nabotjekkene, men fanger stadig ægte scriptfejl. Ingen ændring i appens adfærd. Suite: 2618.

[1.207.0] — 2026-08-15

Tilføjet — registrér udfaldet af en ansøgning direkte fra trackeren.

Tilføjet

  • Hver trackerrække får en Resultat-handling: vælg hvad der skete (afvist, tilbud modtaget, ansat, tilbud afvist, intet svar, gik videre til samtale), tilføj en valgfri note, forhåndsvis den resulterende status, og registrér den. Registrering arkiverer de indsendte CV- og ansøgningsartefakter og synkroniserer trackeren til den kanoniske tilstand — én deterministisk handling i stedet for manuel redigering.

Noter

  • Ny POST /api/outcome videresender resultat-CLI’en: dryRun:true er en skrivebeskyttet forhåndsvisning (matcher rækken, rapporterer den resulterende tilstand, skriver intet); et rigtigt kald registrerer det. Skrivesikkerhed: resultattypen er begrænset til det kendte sæt, og hvert tekstfelt afvises ved kontroltegn før kaldet (array-argumenter, spawn — ingen shell). tests/outcome-route.test.mjs. Suite: 2618.

[1.206.0] — 2026-08-15

Dokumentation — den indbyggede hjælpeguide dækker nu de fem nyeste funktioner på alle 17 sprog.

Tilføjet

  • Den indbyggede hjælpeguide — og «Spørg hjælpen»-assistenten, der svarer ud fra den — dokumenterer nu fem nyligt tilføjede funktioner: Opsætningslæge (Indstillinger — tjekker dit CV og din profil for huller og efterladte eksempeldata), Find ATS-tavler (Portaler — finder automatisk en virksomheds karrieretavle), «stadig åben?»-tjekket (Tracker — om et opslag stadig er åbent), «genbrug et tidligere CV?»-hintet (CV Studio — markerer, når et allerede tilpasset CV passer til et nyt opslag) og Færdighedslog (Analyse — registrér selvvurderingsscorer). Fem nye underafsnit, oversat til alle 17 sprog.

Noter

  • Guidens struktur vokser til 31 H2 / 118 H3 med paritet garanteret på hvert sprog. Referencedokumentation opdateret: docs/architecture/API.md dokumenterer de fem ruter bag disse funktioner, og rute-/versionstællerne i CLAUDE.md og docs/sdd/CONVENTIONS.md er ajour (36 rutemoduler). Suite: 2610.

[1.205.0] — 2026-08-15

Tilføjet — en færdighedslog til at notere test-/vurderingsresultater.

Tilføjet

  • En ny Færdighedslog (Analyse → Færdighedslog) lader dig notere en selvvurdering — virksomhed, platform, færdighed, score % og en valgfri note — tilføjet til data/assessments.tsv, med en liste over tidligere poster (nyeste først). Token-fri, deterministisk; filformatet styres af forældreprojektets CLI.

Noter

  • Ny GET /api/assessments (relæer assessment-log.mjs’s standard JSON-liste; blød fejl {available:false}) + POST /api/assessments (eksplicit skrivning: felter sendt som array-argumenter til assessment-log.mjs add). Skrivesikkerhed: ethvert tekstfelt med et kontroltegn afvises (en TAB ville bryde en kolonne, et linjeskift injicere en række) → 400 før skrivning; score/tærskel begrænset til 0–100, længder afgrænset. tests/assessments-route.test.mjs. Suite: 2610.

[1.204.0] — 2026-08-15

Tilføjet — et “Opsætnings-doktor”-panel i Indstillinger, der markerer et ufuldstændigt CV/profil eller eksempeldata.

Tilføjet

  • Indstillinger → Opsætnings-doktor kører nu et token-frit tjek af dit cv.md og config/profile.yml og viser blokerende problemer (manglende filer/felter) og advarsler (efterladt eksempel-/pladsholderdata, hardkodede tal) — så du fanger en ufuldstændig opsætning, før den svækker dine scanninger og tilpasninger. Skrivebeskyttet; gentag med ét klik.

Noter

  • Ny skrivebeskyttet GET /api/cv-sync-check relæer forældreprojektets cv-sync-check.mjs, som skriver tekst + en exit-kode (ingen --json); ruten parser let dens stabile ERROR: / WARN:-linjer til {ok, errors[], warnings[]} — banneret, ikke exit-koden, afgør succes. Fejler blødt {available:false} på selvstændige installationer. tests/cv-sync-check-route.test.mjs. Suite: 2602.

[1.203.0] — 2026-08-15

Tilføjet — et “genbrug et tidligere CV?”-hint i CV Studio.

Tilføjet

  • Når du åbner et gemt jobopslag i CV Studio, sammenligner appen det nu med dine andre gemte opslag (deterministisk ordoverlap, nul tokens) og fortæller, om det nærmeste er nok til at genbruge det tilpassede CV, genbruge det med rettelser eller tilpasse et nyt — så du ikke genskaber fra bunden til en rolle, du allerede har målrettet.

Noter

  • Ny skrivebeskyttet GET /api/jds/:name/reuse relæer forældreprojektets jd-similarity.mjs (Jaccard-overlap + et senioritetsvagt; JSON {decision, score, reason}) én gang per tidligere opslag (fan-out begrænset til 25, bedste match vinder); fejler blødt med {available:false}, hvis scriptet eller tidligere opslag mangler. tests/jd-similarity-reuse-route.test.mjs. Suite: 2594.

[1.202.0] — 2026-08-15

Tilføjet — find en virksomheds ATS-jobboard fra #/portals og begynd at følge det.

Tilføjet

  • På #/portals skriver du et virksomhedsnavn, og appen prober Greenhouse, Ashby og Lever for dens offentlige board — nul tokens, ingen browser — og viser de boards, der findes og aktuelt har ≥1 job. Ét klik føjer det valgte board til de virksomheder, din scanner overvåger. Probing er skrivebeskyttet; skrivning til portals.yml sker kun, når du klikker Tilføj.

Noter

  • Ny server/lib/discover-ats.mjs (fast-host, charset-valideret slug-probe via DNS-fastgjort safeGet, ≤12 prober/forespørgsel) + POST /api/portals/discover (skrivebeskyttet) og POST /api/portals/track (eksplicit skrivning: withFileLock + kirurgisk tekst-splejsning + genparse-vagt + atomar omdøbning; kun kendte ATS-hosts, idempotent). Genbruger scannerens adapter-register. i18n ×17. tests/discover-ats-resolver.test.mjs + tests/discover-ats-route.test.mjs. Suite: 2588.

[1.201.0] — 2026-08-15

Rettet — en tracker med lokaliserede eller variant-kolonneoverskrifter vises ikke længere tom.

Rettet

  • Hvis din data/applications.md bruger ikke-engelske eller variant-overskrifter — spansk empresa / puesto / estado / fecha / enlace, eller position / stage / link — læste trackeren dem under de forkerte nøgler og viste tomme Virksomhed / Rolle / Status / Dato / Link-kolonner. Nu foldes disse overskrifter til de kanoniske feltnavne, og trackeren vises korrekt. En helt engelsk tracker parses som før.

Noter

  • Ny HEADER_ALIASES-tabel + en normaliseringsfoldning i parseApplications (server/lib/parsers.mjs); ukendte eller allerede kanoniske overskrifter passerer uændret. tests/tracker-header-aliases.test.mjs. Suite: 2563.

[1.200.0] — 2026-08-15

Tilføjet — et “stadig ledig?”-tjek med ét klik for ATS-hostede job i din tracker.

Tilføjet

  • På #/tracker viser en ansøgning, hvis URL er et Greenhouse / Lever / Ashby / Workday / SmartRecruiters-opslag, nu en “Stadig ledig?”-knap. Ét klik spørger ATS’ets eget offentlige JSON — nul tokens, ingen browser — og viser Ledig / Udløbet / Ukendt, så du kan opdage døde opslag uden at åbne hvert enkelt. Konservativ af design: kun et klart 404/410 læses som Udløbet; alt tvetydigt forbliver Ukendt (aldrig et falsk Udløbet).

Noter

  • Nye server/lib/liveness-core.mjs + liveness-api.mjs og en skrivebeskyttet GET /api/liveness?url= (ingen skrivning, ingen LLM). SSRF-sikker: URL’en gates gennem isValidJobUrl, og ATS-API’et nås kun via DNS-fastgjort safeGet med fast host og charset-validerede stisegmenter. tests/liveness-core.test.mjs + tests/liveness-route.test.mjs. Suite: 2557.

[1.199.0] — 2026-08-15

Rettet — brede tabeller ruller nu vandret i stedet for at blive skåret af.

Rettet

  • På Scan-siden (og i alle andre tabeller — Tracker, Statistik, Forbrug, Dashboard) blev en tabel bredere end vinduet klippet af uden rullebjælke, så de yderste kolonner var uden for rækkevidde. Brede tabeller viser nu en vandret rullebjælke efter behov, så hver kolonne er tilgængelig i enhver bredde.

Noter

  • .table-wrap i public/css/components.css skiftede fra overflow: hidden til overflow-x: auto (som den eksisterende .reports-scroll-container); den afrundede kant bevares. tests/table-wrap-scroll.test.mjs. Suite: 2540.

[1.198.0] — 2026-08-15

Tilføjet — scan-genforsøg bruger nu eksponentiel backoff, jitter og respekterer en rate-limiters Retry-After.

Tilføjet

  • Når et jobboard kortvarigt rate-limiter eller fejler (HTTP 429 / 5xx) midt i en scanning, venter genforsøget nu med eksponentiel backoff + jitter i stedet for en fast kort forsinkelse — et travlt board hamres ikke i samme kadence, og samtidige genforsøg kolliderer ikke igen i lockstep. Et Retry-After fra boardet respekteres (men klemmes, så et fjendtligt Retry-After: 86400 ikke kan stoppe hele scanningen). Permanente fejl (404, afviste omdirigeringer) fejler stadig med det samme — uændret.

Noter

  • Nye parseRetryAfterMs() og den rene computeRetryDelayMs() i server/lib/http-json.mjs; fetchJson fanger nu .retryAfter på et ikke-ok-svar, og fetchJsonWithRetry tager et valgfrit maxDelayMs (standard 8000). tests/http-json.test.mjs (+9). Suite: 2536.

[1.197.0] — 2026-08-14

Tilføjet — følg et Getro VC-jobboard alene ud fra dets careers_url; collection-id’et løses automatisk.

Tilføjet

  • Et fulgt Getro-board (b2venture, Earlybird, Point Nine, …) behøver ikke længere et håndslået numerisk getro_collection. Giv boardets egen careers_url, og id’et løses automatisk fra den side ved første scanning — et enkelt SSRF-sikkert GET læser det numeriske network.id direkte fra sidens indlejrede data. Et eksplicit getro_collection vinder stadig og springer hentningen helt over.

Noter

  • Nye httpsCareersUrl(), extractCollectionId() og den asynkrone resolveCollectionId() i server/lib/sources/getro.mjs; boardsiden hentes via safeGet (DNS-fastgjort, størrelsesbegrænset), og det løste id er stadig host-fastgjort til api.getro.com af assertGetroUrl. Adapteren matcher nu en provider: getro-post med en https careers_url, selv uden id. tests/sources-getro.test.mjs (+8). Suite: 2527.

[1.196.0] — 2026-08-14

Rettet (sikkerhed) — Workday-adapteren validerer et api-endpoint på dets hostnavn, ikke en delstreng.

Rettet

  • En Workday api:-værdi i portals.yml accepteres nu kun, når dens hostnavn er myworkdayjobs.com (eller et .myworkdayjobs.com-subdomæne). Det gamle tjek var en delstreng-match, så enhver URL, der blot indeholdt strengen — f.eks. https://example.com/?x=myworkdayjobs.com — kom igennem og ville være blevet brugt som endpoint. Rigtige Workday-endpoints er upåvirkede. (Rapporteret af CodeQL, #443.)

Noter

  • Ny isWorkdayApi() parser URL’en og tjekker hosten (server/lib/portals/adapters/workday.mjs). tests/workday-adapter-endpoint.test.mjs (+1). Suite: 2522.

[1.195.0] — 2026-08-14

Ydelse (scanner) — repost-detektion forbliver hurtig på store scan-historikker.

Ydelse

  • Detektion af dublet-opslag degraderer ikke længere til O(N²) på en stor scan-history.tsv. Titelgrupperingen pr. virksomhed var en indlejret løkke, der betalte et fuldt roleFuzzyMatch på hvert par; nu er det et inverteret indeks — buckets efter nøjagtig titel i én gennemgang, derefter fuzzy-match kun mellem FORSKELLIGE buckets, der deler et diskriminerende (ikke-baseline) token. Outputtet er identisk — de samme repost-klynger — bevist med en differentiel test mod den gamle algoritme på 200+ tilfældige historikker.

Noter

  • groupRowsByTitle i server/lib/detect-reposts.mjs (eksporteret til den differentielle test). tests/detect-reposts-grouping.test.mjs (+2). Suite: 2521.

[1.194.0] — 2026-08-14

Rettet (scanner) — Workday-karrieresider med en enkelt-segment-URL scannes nu korrekt.

Rettet

  • Workday-adapteren parser nu karriere-URL’er hvis sti er ét segment — f.eks. https://parsons.wd5.myworkdayjobs.com/Search, .../KBR_Careers, .../Careers. Før faldt sitet tilbage til External, så adapteren ramte det forkerte CXS-endpoint, og en probe kunne se sund ud uden at returnere noget. Den tager nu det første ikke-tomme sti-segment som site (og dropper et sprogpræfiks som en-US); det dokumenterede /en-US/External er uændret. (Rapporteret i #255.)

Noter

  • Strukturel sti-parsing i server/lib/portals/adapters/workday.mjs. tests/workday-adapter-endpoint.test.mjs (+7). Suite: 2519.

[1.193.0] — 2026-08-14

Tilføjet (statistik) — en “Stille efter samtalen”-fane, der fremhæver samtaler værd at følge op på.

Tilføjet

  • En Stille efter samtalen-fane i #/stats: samtaler, der er blevet stille ud over et høflighedsvindue (30 dage som standard), der samler dine aktive samtaler og trackeren — med hvor længe hver har været stille, datoen for sidste samtale og årsagen. En blid påmindelses-/afslutningsliste; kun forslag, aldrig en påstand om afslag. Ingen tokens.

Noter

  • Ny GET /api/stats/rejection-latency-rute (fail-soft {available:false}). tests/stats-rejection-latency-route.test.mjs (+2). +10 i18n-nøgler ×17; #/stats help-hint fra 7→8 faner. Suite: 2510.

[1.192.0] — 2026-08-14

Tilføjet (cv-studio) — en “Faktatjek dit CV”-gate, der fanger tal, du aldrig har haft.

Tilføjet

  • Et Faktatjek dit CV-kort i #/cv-studio: indsæt et tilpasset CV eller følgebrev og tjek hver påstået måling og faktum mod dit rigtige CV, profil og two-pager. Du får en pass / warn / block-dom plus de præcise opdigtede målinger, ubegrundede fakta og forbudte / rådgivende fraser. Ingen LLM; intet gemmes.

Noter

  • Ny POST /api/cv-studio/verify-facts-rute: skriver teksten til en engangs-temp-fil og kører verify-cv-facts.mjs, idet den stoler på JSON-dommen, selvom scriptet afslutter med 1 ved block. tests/cv-studio-verify-facts-route.test.mjs (+4). +15 i18n-nøgler ×17. Suite: 2508.

[1.191.0] — 2026-08-14

Tilføjet (statistik) — en “Hvad du skal lære næst”-fane, der rangerer de færdigheder, du bør lære først.

Tilføjet

  • En Hvad du skal lære næst-fane i #/stats: en opsummering på tværs af hele trackeren — de manglende færdigheder, der oftest sænkede en lav match, vægtet (efter 5−match-score på hver rapport) og opdelt i Critical / High / Medium — plus dem, dit CV/profil allerede dækker. Skrivebeskyttet, kun forslag, ingen tokens.

Noter

  • Ny GET /api/stats/upskill-rute ({ error }-felt ved for lidt data; fail-soft {available:false}). tests/stats-upskill-route.test.mjs (+3). +15 i18n-nøgler ×17. Suite: 2504.

[1.190.0] — 2026-08-14

Tilføjet (tracker) — et “Virksomhedshistorik”-panel, der viser hvilke virksomheder der faktisk svarer dig.

Tilføjet

  • Et Virksomhedshistorik-kort på #/tracker: vælg en virksomhed og få skrivebeskyttet bevis — hvor lydhør den har været over for dig (tavs over for dig / blandet / har svaret før) og om den samme stilling bliver genopslået — samlet fra din tracker, opfølgninger og scan-historik. Ingen tokens; scanneren kaldes aldrig.

Noter

  • Ny GET /api/stats/company-history[?company=]-rute (fail-soft {available:false}). tests/stats-company-history-route.test.mjs (+3). +18 i18n-nøgler ×17. Suite: 2501.

[1.189.0] — 2026-08-14

Rettet (scanner) — senioritetsniveauer skrevet med romertal tæller nu også på ikke-latinske titler.

Rettet

  • Tier-klassifikatoren bag skip_tiers læser nu et niveausuffiks i romertal (I / II / III / IV / V) efter jobordet i enhver skrift — “Инженер III”, “エンジニア I”, “Ingénieur IV” — ikke kun efter ASCII-ord. Før blev et niveautal efter et ikke-latinsk ord ignoreret, og opslaget faldt til mid, så skip_tiers: [senior] eller [entry] overså dem.

Noter

  • Skrift-uafhængig lookbehind i server/lib/classify-tier.mjs; fjernede en død dublet-Sr.-matcher. tests/classify-tier.test.mjs (+1). Suite: 2498.

[1.188.0] — 2026-08-14

Rettet (UI) — de primære handlingsknapper sidder ikke længere klods op ad sideundertitlen.

Rettet

  • Den primære handlings-/kontrolrække på Ugentligt interviewresumé, Finansierede virksomheder, Portaler, Karriereplan og Karriereorientering har nu en passende topmargin, så knappen får luft under undertitlen i stedet for at støde op mod den.

Noter

  • Regressionsvagt tests/lead-row-top-margin.test.mjs (+5). Suite: 2497.

[1.187.0] — 2026-08-14

Rettet (scanner) — skip_tiers-indstillingen virker igen: opslag, du bad om at springe over efter senioritet, frasorteres.

Rettet

  • En skip_tiers:-liste i portals.yml (fx skip_tiers: [intern, entry]) respekteres nu af scanningen. Hvert opslags titel klassificeres i et niveau (intern / entry / mid / senior) og frasorteres, hvis niveauet er på din liste. Før kørte scanningen titel- / lokations- / indholds- / tillidsfiltrene, men uden niveaufilter, så skip_tiers blev stiltiende ignoreret. Titler uden niveauord falder til mid (så skip_tiers: [mid] frasorterer også de fleste almindelige opslag), og klassifikatoren læser det VENSTRESTE niveauord.

Noter

  • Nyt rent modul server/lib/classify-tier.mjs (classifyTier + buildTierFilter), koblet til EN- og RU-scannernes filterkæder. tests/classify-tier.test.mjs (+7). Suite: 2492.

[1.186.0] — 2026-08-14

Tilføjet (CV Studio) — et “Kompetencekløft”-panel: hvilke af et jobs krævede færdigheder dit CV nævner, antyder eller mangler.

Tilføjet

  • Et nyt Kompetencekløft-panel i CV Studio. Vælg en gemt jobbeskrivelse, og det sorterer hver krævet færdighed i nævnt i dit CV, antydet i dit CV eller manglende — ordsammenligning uden LLM, intet gemmes. En note om lav tillid vises, når opslaget ikke havde en tydelig kravsektion.

Noter

  • Ny GET /api/jds/:name/skill-gap (jobnavnet saneres og bekræftes under jds/, før det bliver et argument; blød fallback til {available:false} uden scriptet). +13 i18n-nøgler ×17. Tests: tests/jds-skill-gap-route.test.mjs (+4, inkl. afvisning af path-traversal). Suite: 2485.

[1.185.0] — 2026-08-14

Tilføjet (statistik) — en “Tragt og hastighed”-fane: hvordan din tragt sammenlignes med markedet, og hvor hurtigt du bevæger dig mellem trin.

Tilføjet

  • En ny Tragt og hastighed-fane i Statistik viser dine svar- og samtale-rater ved siden af markedets benchmark-intervaller (med forbeholdene om lille stikprøve og udvælgelsesbias), en venteliste over igangværende ansøgninger ud over det typiske første-svar-vindue, og mediandage pr. trin (Ansøgt → Svaret → Samtale → Tilbud) — langsomme rækker højrecensureres, så de ikke skævvrider medianerne. Skrivebeskyttet og nul tokens; læser kun din egen tracker.

Noter

  • Ny GET /api/stats/funnel (blød fallback til {available:false} uden scriptet). +18 i18n-nøgler ×17. Tests: tests/stats-funnel-route.test.mjs (+2). Suite: 2481.

[1.184.0] — 2026-08-14

Rettet (UI) — Dashboardets hurtighandlingsfliser flugter nu i et jævnt gitter.

Rettet

  • På Dashboardet (Kommandocentralen) blev en gruppe på 3 fliser bredere end en på 4, så sektionerne stod med en ujævn højrekant. Hver gruppe bruger nu lige brede kolonner (4 på en bred skærm, ned til 3 / 2 / 1 når vinduet bliver smallere), så alle fliser har samme størrelse og deres højrekanter flugter.

Noter

  • Kun CSS (.qa-grid: fast repeat(N, minmax(0,1fr)) i stedet for auto-fill). Beskyttet af tests/dashboard-grid-align.test.mjs (+2). Suite: 2479.

[1.183.0] — 2026-08-14

Tilføjet (scanner) — smartere dublet-registrering: det samme job genopslået med et sporingslink vises ikke længere to gange.

Tilføjet

  • Scanneren genkender nu et opslag ud fra en kanonisk URL-nøgle, så det samme job genopslået med en sporingsparameter (?utm_…, gclid, …), over http vs https, eller med en afsluttende skråstreg / #fragment behandles som det ene opslag, det er — ingen dublet-række i dine scanresultater eller pipeline og ingen spildt evaluering af et job, du allerede har set. Reelt forskellige opslag (et bevaret funktionelt id som gh_jid) tælles stadig hver for sig.

Noter

  • Nyt server/lib/url-key.mjs, koblet til begge scanneres dedup og pipeline-skriveren. Under-normaliserer med vilje — fletter aldrig to forskellige opslag. Tests: tests/url-key.test.mjs (+5), tests/parsers.test.mjs (+1). Suite: 2477 (+6).

[1.182.0] — 2026-08-14

Rettet (scanner) — lønintervaller vises nu ens på alle sprog.

Rettet

  • Lønbeløb i scan- og tracker-rækker bruger de sprogneutrale symboler ≥ og ≤ (fx ≥ 120000 EUR, ≤ 90000) i stedet for de engelske ord “from” / “up to”, der sivede uoversat ind i ikke-engelske UI’er. Gælder alle tavler med et ensidet interval (Getro, Remotli, Manfred, Agentic Jobs, JustJoin, Jobicy); tosidede intervaller (100000–150000 USD) var allerede neutrale.

Noter

  • Kun visning — klientens lønfilter parser tallene uanset præfiks, så filtrering er uændret. Suite: 2471.

[1.181.0] — 2026-08-14

Tilføjet (scanner) — Getro-jobtavler viser nu løn, alle lokationer og fjernstillinger.

Tilføjet

  • Getro-scanneren (fondes talentnetværkstavler) viser nu en løn på hvert job (årligt interval + valuta), lister alle lokationer i stedet for kun den første og markerer fjern-stillinger. Et Getro-job i din scanning og tracker bærer nu samme løn- + lokationsdetalje som de øvrige tavler.

Noter

  • Kun scanner; ingen ny afhængighed, ingen ændring af rute / CSP / SSRF. Tests: tests/sources-getro.test.mjs (+5). Suite: 2470 (+5).

[1.180.0] — 2026-08-14

Rettet (MELLEM, rapporter) — #/reports-listen er nu en tabel, og en reel score, som en Machine Summary-pladsholder skjulte, gendannes.

Rettet

  • #/reports-listen er en tabel (Rapport · Dato · Legitimitet · Score), ikke et gitter med 4 kort. En lang “Score ikke fundet”-chip pressede titelkolonnen næsten til nul, og kortets overflow-wrap: anywhere brød rapportnavnet ét tegn ad gangen. Nu har hvert felt sin egen kolonne, navnecellen ombrydes ved ord, og tabellen ruller vandret på en smal skærm (ny .reports-scroll-container). Ny i18n-nøgle rep.colReport ×17.
  • En reel score i brødteksten (**Итоговый балл:** 1.8 / 5) skjules ikke længere af en Machine Summary-pladsholder (score: —). Når ## Machine Summary-blokken bar en ikke-numerisk eller uden for området-score, optog den den parsede score-plads og blokerede fed værdiform-fallback, så rapporten viste “Score ikke fundet” trods en reel X / 5 i brødteksten. parseReportHeader gendanner nu brødtekstens værdiform, når intet brugbart tal overlevede (trin 4.5).

Noter

  • Kun klient + parser; ingen ændring af rute / CSP / SSRF / forælderskrivning. Tests: tests/reports-table.test.mjs (+5), tests/report-header-locale.test.mjs (+2). Suite: 2465 (+7).

[1.179.0] — 2026-08-13

Ændret (LOW, scanner) — 20 duplikerede HTML-entitetsdekodere samlet i det delte modul (paritets-opfølgning, lukker worklisten).

Ændret

  • 20 scraping-kilder havde hver sin egen decodeEntities/decodeXmlEntities (+ en fromCodePoint-hjælper) — kopier der var drevet fra hinanden (tre kunne kaste en RangeError, rettet i v1.172.0; andre tillod NUL/C0 eller fejltolkede &#1a2;). Alle går nu gennem den ene server/lib/html-entities.mjs (XML 1.0 Char-sikker dekoder), hvilket fjerner ~237 linjers duplikering. De 8 RSS-lignende kilder fik &nbsp;-dekodning (før håndterede de kun 5 entiteter); cryptocurrencyjobs’ bevidste dobbelt-dekodning bevares via et alias. hh beholder sin egen dekoder (den håndterer &mdash;/&ndash;, uden for de delte 6). En ny vagt-test fejler, hvis en kilde igen laver en lokal dekoder.

Noter

  • Adfærdsbevarende refaktorering; ingen ændring af rute / CSP / SSRF / forælderskrivning. Tests: tests/decoder-consolidation.test.mjs (+2). Suite: 2458 (+2).

[1.178.0] — 2026-08-13

Rettet (LOW, forælder-paritet) — to forældede konstanter opdateret, så de matcher forælderen (PARENT-SYNC GAP #4 + #5).

Rettet

  • Browser-User-Agent (GAP #4) — BROWSER_LIKE_USER_AGENT (sendt af workable/workday/oraclecloud/a16z/eightfold for at komme gennem WAF/bot-gates) hævet fra Chrome 131 til 151, så den matcher forælderens user-agent.mjs; en gammel build udfordres oftere. Beskyttet af en Chrome major ≥ 151-test.
  • Tracker-tilstands-FALLBACK (GAP #5) — den sidste udvej FALLBACK i states.mjs (bruges kun når den live templates/states.yml er ulæselig — frisk klon / CI-isoleret rod) fik forælderens tyrkiske status-aliaser (#2615): değerlendirildi, başvuruldu, yanıt verildi, mülakat, teklif, reddedildi, iptal edildi, uygun değil, kabul edildi/işe alındı. I produktion leverede den live fil dem allerede.

Noter

  • Kun to konstanter; ingen ændring af rute / CSP / SSRF / forælderskrivning. Tests: tests/http-json.test.mjs (+1) + tests/states.test.mjs (+1). Suite: 2456 (+2).

[1.177.0] — 2026-08-13

Rettet (MEDIUM, scanner) — csod (Cornerstone) returnerede 0 job på lejere, der beskytter søge-API’et med session-cookies (parent #2769, PARENT-SYNC GAP #1).

Rettet

  • Nogle Cornerstone-lejere sætter session-cookies på bootstrap-karrieresidens forside og svarer 401 CSOD Unauthorized på søge-API’et, medmindre de cookies kommer tilbage sammen med det anonyme bearer-token. sources/csod.mjs læser nu bootstrap via en ny fetchResponse-hjælper, bygger en Cookie-header af dens Set-Cookie-værdier (cookieHeaderFrom — kun name=value, jar-semantik) og gentager den på søge-POST’en. Kun samme origin (host fastlåst + redirect:'error'), så session-cookies aldrig kan nå en tredjepart; en lejer uden cookies opfører sig som før.

Noter

  • Ny server/lib/http-json.mjs::fetchResponse (additiv; eksisterende kilder upåvirket). Ingen ændring af rute / CSP / SSRF / forælderskrivning. Tests: tests/sources-parity-v1118a.test.mjs (+1). Suite: 2454 (+1).

[1.176.0] — 2026-08-13

Rettet (MEDIUM, rapporter) — en score under en fed etiket, som RU-tabellen ikke lister, viste stadig “Score not detected” (FIND-5).

Rettet

  • To RU-rapporter skrev scoren som **Итоговый балл:** 1.8 / 5 / **Скор:** 1.8 / 5 — fede etiketter, som REPORT_LABELS.ru ikke opregner (den kender kun “Оценка”/“Балл”), så scoren forblev uparset. I stedet for at udvide synonymlisten falder parseReportHeader nu tilbage på værdiformen: en brøk over /5-rubrikken under EN HVILKEN SOM HELST fed etiket. Den er sproguafhængig, immun over for en overskrift (ingen **, ingen /5-værdi) og afviser en dato som 5/5/2026 (negativt lookahead på nævneren).

Noter

  • Kun server-parser; ingen ændring af rute / CSP / SSRF / forælderskrivning. Tests: tests/report-header-locale.test.mjs (+2). Suite: 2453 (+2).

career-ops-ui v1.267.1 · page 3/9 · mirror of the project changelog for cvstart.org