Değişiklik günlüğü

GitHub

Her önemli değişiklik, sürüm sürüm. Aynı dosya depoda yer alır ve 19 dilin tümüne çevrilmiştir.

[1.236.0] — 2026-09-18

Üst proje eşdeğerliği — career-ops main @ 6a9c84c (VERSION 1.33.0, 128 commit). İki yeni kaynak ve üç yansıtılmış düzeltme — bunlardan ikisi burada ilanları sessizce kaybediyordu.

Eklendi

İki tarayıcı kaynağı, 92 → 94 (89 EN + 5 RU). Python.org Jobs (pythonorg) panonun herkese açık akışını (feed) okur; işveren atfı zorunludur, bu yüzden başlığında hiçbir işveren adı geçmeyen bir satır, portal girdisinin adıyla doldurulmak yerine düşürülür. Generalist World (generalist-world) panonun kartlarını kazır ve ayrıştıramadığı biçimlendirmede gürültülü biçimde başarısız olur — değişen bir kart biçimi, boş bir pano gibi okunmak yerine fırlatır; kazınan bir kaynağı güvenilmez kılan başarısızlık biçimi tam olarak budur. İkisi de #/scan Kaynak filtresinde görünür, ikisi de ana bilgisayara sabitlenmiştir (çıpalı regex, yalnızca HTTPS) ve ikisi de uçtan uca sahte aktarım (fake-transport) takımlarıyla yönlendirilir (43 ve 36 durum).

Düzeltildi

Birkaç şehirde açık bir Workday pozisyonu, bir konum filtresi tarafından düşürülüyordu. Workday’in liste uç noktası, diğer her ilanın bir yer taşıdığı yerde çok konumlu bir ilanı bir sayı ile yanıtlıyor: "53 Locations". Bu bir konum değildir ve buildLocationFilter, büyük/küçük harfe duyarsız alt dize ile eşleşir — bu yüzden Austin’de ve diğer 52 şehirde açık bir pozisyon hiçbir allow: [austin] girdisiyle eşleşmiyor ve eleniyordu, oysa aynı pozisyon tek başına listelendiğinde geçiyordu. Üst projede üç kiracı genelinde ölçüldü: 291 ilandan 53’ü yer tutucuydu, dolayısıyla bu sıra dışı değil, olağan durumdur. İlanın gerçek yerleri yalnızca CXS detay belgesinde bulunur, bu yüzden her yer tutucu artık ona karşı bir ek GET’e mal oluyor, girdi başına 200 ile sınırlı — sınırın ötesinde yer tutucu, sahtelenmek yerine görünür bırakılıyor, çünkü çözülmemiş bir ilan asla çözülmüş gibi okunmamalıdır. Başarısız veya yersiz bir detay, ilanı listenin döndürdüğü haliyle bırakır: görünür bir "53 Locations", neyin çözülemediği konusunda dürüsttür, oysa boşaltılmış bir konum her filtreden sessizce geçerdi. Aynı GET ayrıca startDate taşır, bu yüzden zenginleştirilmiş bir ilan, liste uç noktasının göreli düzyazısı ("Posted 30+ Days Ago" → undefined) yerine tam olarak tarihlendirilir; çıplak bir YYYY-MM-DD olmayan her şey, ISO olmayan geri dönüşü uygulamaya özgü olan Date.parse’tan geçirilmek yerine olduğu gibi bırakılır. Belirtilen bir seviye artık iki ilanı tek bir yeniden gönderiye çökertmiyor. "Insurance Specialist II", işverenin bu ilanın kardeşi olmadığına dair kendi ifadesidir — tek bir taban başlık altında farklı bir ücret bandı, kapsam ve ilan numarası. Belirteçleyici (tokenizer) bunu göremiyordu: w.length > 3, VIII’e kadar her Romen rakamını ve her tek haneli rakamı düşürür, bu yüzden "Insurance Specialist" ve "Insurance Specialist II" özdeş biçimde belirteçleniyor, kusursuz bir Jaccard oranı alıyor ve yeniden gönderi dedektörü ikinciyi birincinin yeniden listelenmesi olarak işaretliyordu. web-ui’nin role-matcher.mjs’inde seviye işleme hiç yoktu, bu yüzden bu değişiklik üst projenin mekanizmasının tamamını taşıyor: seviyeler, Romen ve Arap rakamları tek bir sayıya katlanarak çıkarılıyor ("Nurse II" ve "Nurse 2" aynı ifadedir — ve bu çift daha önce yanlışlıkla farklı sonuç veriyordu), belirtilen iki seviye uyuşmalıdır ve yalnızca bir tarafta bulunan bir seviye, her başlık da diğerinde bulunmayan bir sözcük taşımadıkça gevşek bir yeniden yazım olarak ele alınır — ki bu bir süsleme değil, iki uyuşmazlıktır. Bir filtreye sabitlenmiş bir Avature panosu yine de tüm küresel panoyu geziyordu. Avature’ın arama arayüzü opak facet parametreleri üretir (?42386=[812132] bir ülke filtresidir) ve portals.yml içinde daraltılmış bir panoyu sabitleyen bir operatör, taramanın onu gezmesini bekler. resolveSearch, URL’yi ${origin}${path} olarak yeniden kuruyor ve sorgu dizesini tamamen düşürüyordu — bu yüzden ilki dahil her istek, kiracının tüm panosunu geziyordu: daha fazla sayfa, daha fazla istek ve operatörün kasıtlı olarak filtrelediği ilanlar. Facet’ler artık sayfalanan her istekte taşınıyor; kendi jobOffset’imiz en son uygulanıyor, böylece başıboş, aynı adlı bir facet sayfalamayı asla ele geçiremez.

Güvenlik

devalue 5.8.1 → 5.9.2 (astro üzerinden dolaylı olarak), tek açık Dependabot uyarısını kapatıyor — hatalı biçimli girdide bir hizmet reddi. Yalnızca site bağımlılığı; hiçbir çalışma zamanı kodu değişmedi.

Notlar

Taşınmayanlar, her biri gerekçesiyle birlikte. Üst proje, paylaşılan 10 saniyelik varsayılana karşı lever’a 30 saniye ve manfred‘e 25 saniye zaman aşımı verdi — bir taşınmayan (no-port): web-ui’nin tarama aktarımı burada zaten 60 saniyeye izin veriyor (DEFAULT_SCAN_TIMEOUT_MS), bu yüzden her iki pano da orada düzeltmenin verdiğinden daha fazla paya buradan sahip. **iCIMS’**in ikiye katlanmış careers- ön eki de burada oluşamaz: web-ui kiracı kökenini doğrudan api/careers_url’den alır ve bir ana bilgisayarı hiçbir zaman bir kiracı adından kurmaz; onun yeni yedek-ana-bilgisayar gezintisi, üst projenin daha gevşek yapılandırması için bir özelliktir, bir kusur düzeltmesi değil. deutschebahn ve manfred, geçici iptalde yeniden deneme kazandı; web-ui’nin 60 saniyelik tavanı bunu çok daha az acil kılıyor — taşınmak yerine not edildi, böylece gelecekte uzun bir gezinti zaman aşımı yaşandığında denenecek bilinen bir ilk şey olsun. 128 commit’lik farkın geri kalanının tamamı CLI, doğrulayıcı, dashboard veya web/ (üst projenin kendi ön ucu): liveness-browser, check-jd-archive, verify-ats/verify-portals/verify-cv-facts, update-system, set-status, audit-portals, discover-ats, scaffolder, test-all, eklenti manifestoları. Çekme sonrası fork ayrışmaları yeniden doğrulandı: providers/telegram-channel.mjs’deki Kiril \p{L} düzeltmesi, fork’un kendi providers/telegram.mjs’i, web/src/lib/clis.ts içindeki hermes. Üst kaynak career-ops-hq/main tamamen birleştirilmiş durumda (0 commit eksik). 3066 → 3164 test; yardım artık 17 paketin tümünde 94 bağdaştırıcı (89 EN + 5 RU) belirtiyor ve başlık yapısı 32 H2 / 122 H3’te değişmeden kalıyor.

[1.235.0] — 2026-09-16

Üst proje eşdeğerliği — career-ops main @ 68e6b94 (VERSION 1.33.0, 42 commit). İki yansıtılmış düzeltme; bunlardan biri burada MokaHR ilanlarını sessizce kaybediyordu.

Düzeltildi

Aynı MokaHR panosundan ikinci bir iş ilanı eklenmek yerine yok oluyordu. url-key.mjs, bir ilan URL’sini bir karşılaştırma anahtarına indirger ve fragment’i koşulsuz olarak düşürüyordu — mantıklıydı, çünkü neredeyse her fragment yalnızca sunuma yöneliktir (#apply, #section-2). MokaHR, kendi kayıt defterimizdeki istisnadır: ilanları …/social-recruitment/{tenant}/{id}#/job/{n} biçimindedir; burada bir tenant’taki her iş aynı yolu paylaşır ve ilan kimliği yalnızca fragment içinde bulunur. Böylece hepsi tek bir anahtara normalize ediliyordu. Düzeltmeden önce ölçüldü: hatta (pipeline) iki farklı MokaHR ilanı yapıştırın, sonunda tek bir satır kalıyor — ne hata, ne uyarı, fark edilecek hiçbir şey yok; tarayıcının tazelik filtresi (en-scanner.mjs) aynı anahtarı okuyor, dolayısıyla o tenant’tan herhangi bir iş tarama geçmişine girdiğinde, diğer tüm işler “zaten görüldü” olarak eleniyordu. normalizeUrl artık tanınan bir #/job/{id} veya #/jobs/{id} rotasını, fragment düşürülmeden önce yalnızca karşılaştırma amaçlı bir sorgu anahtarına yükseltiyor — MokaHR, önceden yazılmış anahtarların karşılaştırılabilir kalması için yerleşik mokahr_job_id adını koruyor, diğer her ana bilgisayar ise dahili bir _career_ops_fragment_job_id alıyor. Yükseltilen kimlik eklenir, ayarlanmaz: bu parametreyi zaten taşıyan bir URL farklı bir ilanın kimliğini tutar ve onun üzerine yazmak, anahtarın tam olarak ayrı tutmak için var olduğu iki şeyi birleştirir. Tanınmayan her fragment hâlâ çöküyor — zaten doğru olan yarı budur. accept-encoding artık her kaynak isteğinde sabitleniyor. Ayarlanmadan bırakıldığında Node, kendi undici derlemesinin sunduğu her şeyi müzakere eder; Node ≥ 23’ten itibaren buna zstd de dahildir ve amazon.jobs’un zstd yanıtı tam olarak 1024 bayt’ta, 200 durum koduyla kesilmiş olarak geri dönüyor — bu yüzden hata, bir aktarım hatası değil de bozuk bir API gibi okunan Unterminated string in JSON at position 1024 şeklinde görünüyor. Artık her istek gzip, deflate, br gönderiyor. Bizim çalışma zamanlarımızda bu bir onarım değil, önleyici bir tedbirdir: Node 18/20/22 — CI matrisi ve sunucu (22.22.1) — varsayılmak yerine doğrudan doğrulanarak gzip, deflate gönderiyor, dolayısıyla burada hiçbir şey kesilmedi; bugün değişen şey, bu sürümlerin varsayılan olarak istemediği ama doğru şekilde çözebildiği br’nin artık sunulmasıdır. Varsayılan, incelemeye değer olan kısım olan büyük/küçük harfe duyarsız biçimde uygulanıyor: başlık (header) adları büyük/küçük harfe duyarsızdır ve fetch, aynı ada sahip iki girdiyi tek bir virgülle ayrılmış değerde birleştirir; bu yüzden Accept-Encoding: identity geçiren bir çağıran, aksi takdirde gzip, deflate, br, identity gönderilmiş olurdu.

Notlar

Başlıklar (headers), fetchImpl sınırında düz bir nesne (plain object) olarak kalıyor; oysa üst proje fetch’e bir Headers örneği veriyor. Bu, bir gözden kaçırma değil, bilinçli bir ayrışmadır: web-ui’nin fetch yardımcıları enjekte edilebilir bir fetchImpl alır ve 45 kaynak test takımı, yakaladıkları şeyden opts.headers['User-Agent']’ı okur — bir Headers örneğinin köşeli parantezle erişimi yoktur, bu yüzden sadık taşıma, uygulamanın değil davranışın (büyük/küçük harfe duyarsız geçersiz kılma, çağıran kazanır) taşınmasıdır. Çağıranın nesnesi kopyalanır, asla mutasyona uğratılmaz, çünkü birkaç kaynak tek bir başlık sabitini paylaşır. Üst projenin eşlik eden düzeltmesi — varsayılan user-agent’ı büyük/küçük harfe duyarsız biçimde uygulamak — bir taşınmayan (no-port) değişikliktir: web-ui zaten hiçbir varsayılan UA enjekte etmez, her kaynak kendi panosunun gerektirdiğini ayarlar, dolayısıyla bir çağıranın User-Agent’ının çakışacağı bir varsayılan yoktur. İki yeni test takımı ve üç yeni durum bu çifti sabitliyor: tests/http-accept-encoding.test.mjs (tam olarak sabitlenen değer, dört fetch yardımcısının her biri ve üç farklı büyük/küçük harf biçimi altında bir çağıran geçersiz kılması — birleştirme hatasının ürettiği ikinin aksine, tek bir accept-encoding anahtarının hayatta kaldığını doğrular) ve anahtar yerine kullanıcıya görünen dikişi (seam) sınayan tests/parsers-pipeline-hash-route.test.mjs: iki MokaHR ilanının ikisi de hatta ulaşmalı, aynı ilanın dört farklı yazımla yeniden yapıştırılması yine tek bir satıra çökmeli ve kozmetik bir fragment bir kimliğe dönüşmemelidir. Hepsinin önce başarısız olduğu doğrulandı. Sabitlemenin kendisi taşıma katmanında yaşıyor, yalnızca bu yardımcılarda değil: 92 kaynaktan 25’i enjekte edilen fetchImpl’i doğrudan çağırıyor ve onlardan hiç geçmiyor; bu yüzden onu her iki tarayıcının gerçekten enjekte ettiği sarmalayıcı olan makeTimeoutFetch uyguluyor — tüm kaynakların paylaştığı tek geçiş noktası. (Üst projenin bir eşdeğere ihtiyacı yok: providers/_http.mjs onun tek taşıma katmanı.) Yapısal bir bekçi artık yeni bir kaynak kendisine verilen taşıma yerine doğrudan fetch çağırırsa CI’yı düşürüyor; bir davranış senaryosu da 25’ten biri olan greenhouse’u sarmalayıcıdan geçirerek başlığın gerçekten hatta çıktığını kanıtlıyor. Taşınmayanlar, gerekçesiyle birlikte: liveness-browser.mjs (kafalı-Playwright (headed) yeniden kullanım koruması — web-ui kafalı bir tarayıcı çalıştırmıyor), check-jd-archive.mjs (web-ui aktarımı yok), test-all.mjs (üst projenin test koşucusu; fork’un vpFixtureEnv ayrışması bozulmadan duruyor), web/ (üst projenin kendi ön ucu, yansıtılmıyor), eklenti manifestoları ve SIGNATURES.md (yalnızca depoya özgü). batch/batch-runner.sh (sed ilişkilendirmesinden önce kaçışlı & işaretleri) ve jd-skill-gap.mjs (cv.md’yi veri kökünden çözümler) salt okunur olarak aktarılıyor — web-ui, üst projenin kopyalarına shell ile bağlanıyor, bu yüzden ikisi de burada kod değişikliği olmadan geliyor; jd-skill-gap olanı ise /api/jds/:id/skill-gap aktarımını daha doğru hale getiriyor: cv.md artık sürecin başlatıldığı dizin yerine veri kökünden çözümleniyor. Çekme sonrası fork ayrışmaları yeniden doğrulandı: providers/telegram-channel.mjs’deki Kiril \p{L} düzeltmesi, fork’un kendi providers/telegram.mjs’i, web/src/lib/clis.ts içindeki hermes. Kaynak sayısı 92’de (87 EN + 5 RU) değişmedi, dolayısıyla yardım dokunulmadan kaldı. 3042 → 3066 test.

[1.234.0] — 2026-09-15

Üst proje eşdeğerliği — career-ops main @ 56cce8f (VERSION hâlâ 1.32.0, 1.32.0’dan 58 commit ileride). 15 kaynak genelinde tek bir yansıtılmış düzeltme, üstüne bir daha geri gelmemesini sağlayan bir koruma.

Düzeltildi

Tek bir hatalı biçimli iş ilanı kimliği artık tüm sayfayı boşaltmıyor. encodeURIComponent, tek başına kalan bir UTF-16 vekil karakterinde (surrogate) URIError fırlatır ve bir JSON yükü böyle bir karakter taşıyabilir — JSON.parse('"\\uD800"') bunu korur. On beş kaynak, her ilanın URL’sini ana bilgisayarın denetlediği bir kimlik veya slug’dan, ayrıştırma döngüsünün içinde oluşturuyordu; bu yüzden tek bir bozuk ilan döngüyü iptal ediyor ve o sayfadaki tüm işleri kaybettiriyordu; hiçbir şey kaynak hatası olarak günlüğe yazılmıyordu, çünkü istisna, şirket başına yakalama bloğunun raporlayacak bir şeyi olmadan önce yığını çözüyordu. Üst proje bunu providers/_safe-url.mjs içinde düzeltti (safeEncodeURIComponent → URIError’da null, başka her şeyi yeniden fırlat) ve her döngünün kimliğini bu yardımcıdan geçirdi; null durumunda yalnızca o tek ilan düşürülüyor. Bu yardımcı artık server/lib/sources/_safe-url.mjs konumunda ve aynı değişiklik yansıtılan on üç kaynağa uygulandı — alibaba, arbeitsagentur, bamboohr, feishu-jobs, garena, jibeapply, manfred, meituan, mokahr, phenom, thehub, tkms, vdab — ve aynı döngü biçimine ve aynı gizli fırlatmaya sahip, yeni korumanın ilk çalıştırmasında ortaya çıkardığı yalnızca web-ui’ye özgü iki kaynağa, jobstreet ve trudvsem’e. Kapsam bilinçli olarak sınırlı: yalnızca API kaynaklı kimlikler bu yardımcıdan geçiyor. Yapılandırmadan türetilen değerler sıkı kodlamayı koruyor ve gürültülü biçimde başarısız oluyor — garena’nın office’i (bir portals.yml segmenti) fırlatan urlSegment’te kalıyor, API id’si ise null döndüren idUrlSegment’i alıyor; csod’un corpName’i ve 4dayweek’in SLUG_RE ile doğrulanan slug’ı, gerekçesiyle birlikte ada göre izin listesine alındı. rheinmetall’in başlık yedeği, hatalı biçimli bir href’te fırlatabiliyordu. Bir kartın başlığı yoksa, başlık decodeURIComponent aracılığıyla URL slug’ından yeniden oluşturuluyor; bu fonksiyon, kazınan href içindeki bozuk bir yüzde dizisinde fırlatıyor — decode tarafında aynı “tek bozuk satır sayfayı öldürür” biçimi. Artık savunmacı biçimde decode ediyor ve ham slug’a geri dönüyor. Kaynak kayıt defteri, _ ön ekli dosyaları atlıyor. Otomatik keşif, kendisi hariç server/lib/sources/ içindeki her .mjs dosyasını içe aktarıyor ve export const meta içermeyen her şey için uyarı veriyordu — bu yüzden yardımcı, açılışta bir uyarı üretiyordu. Üst projenin kuralı benimsendi: baştaki alt çizgi kaynak değildir anlamına gelir; bu tür dosyalar ne içe aktarılır ne de uyarılır. meta’sı olmayan, bildirilmemiş bir dosya yine de uyarı verir ve keşif testi artık her iki yarıyı da doğruluyor (eski filtreye karşı kırmızı olduğu doğrulandı). Sitenin derleme betiği sync-assets.mjs de diskteki bağdaştırıcı dosyalarını aynı kuralla saydığından, yardımcı artık sessiz düşme korumasını tetiklemiyor.

Notlar

tests/sources-url-encoding-surrogate.test.mjs, üst projenin test takımını üç bölümde yansıtıyor: yardımcının sözleşmesi (eşleşmiş bir vekil çift — sıradan bir emoji — yine de encode edilir; değerin kendi toString’inden gelen bir fırlatma çağıranın hatasıdır ve yayılır), on beş kaynağın tümü için kaynak bazlı davranış (bir bozuk kimlik + bir temiz kimlik → fırlatma yok, temiz olan tutulur, bozuk olan düşürülür; her biri kaynağın dışa aktardığı saf ayrıştırıcı üzerinden, thehub için ise sahte bir aktarım ile onun getiricisi üzerinden yürütülür) ve bir kaynak düzeyinde koruma: dönüştürülen her dosya yardımcıyı hem içe aktarmalı hem de çağırmalı, hiçbir dosya onu içe aktarmadan referans veremez ve incelenmemiş hiçbir dosya çıplak bir encodeURIComponent ile iş ilanı URL’si oluşturamaz — eski biçimdeki yeni bir kaynak, suçlu satır numarasıyla CI’da başarısız olur. On beş kaynak bazlı durumun tümünün, taşımadan önce başarısız olduğu doğrulandı. Üst projedeki değişikliklerin geri kalanı, gerekçesiyle birlikte taşınmadı: batch/batch-runner.sh --cli yalnızca CLI’ye özgü bir bayrak (web-ui, toplu çalıştırıcıya shell ile bağlanmıyor); invite-match.mjs artık set-status.mjs’yi kod kökünden çözümlüyor — web-ui bunu iletmiyor; company-funded.mjs aynı safe-url değişikliğini iç yapısında aldı ve /api/company-funded’ın ayrıştırdığı --json çıktı biçimi değişmedi; test-all.mjs yalnızca bir zaman aşımı bütçesini taşıdı (fork’un vpFixtureEnv ayrışması bozulmadan duruyor); web/, üst projenin kendi ön ucudur ve yansıtılmıyor; AGENTS.md/SIGNATURES.md yalnızca depoya özgüdür. Çekme sonrası fork ayrışmaları yeniden doğrulandı: providers/telegram-channel.mjs’deki Kiril \p{L} düzeltmesi, fork’un kendi providers/telegram.mjs’i, web/src/lib/clis.ts içindeki hermes. Kaynak sayısı 92’de (87 EN + 5 RU) değişmedi, dolayısıyla yardım dokunulmadan kaldı. 3022 → 3042 test.

[1.233.2] — 2026-09-10

Düzeltildi — yüksek önem dereceli iki CodeQL js/remote-property-injection uyarısı.

Düzeltildi

Kaydedilen değerleri process.env’e taşıyan döngü, istek gövdesinden kurulan Object.entries(safe) üzerinde dönüyor ve içinde prototip anahtarlarına karşı açık bir koruma taşıyordu. Kod güvenliydi, çünkü safe yalnızca KNOWN_KEYS’ten doldurulur; ama çözümleyici bu kısıtı iki döngü boyunca izleyemez. Artık doğrudan sabit dizi üzerinde dönüyor, dolayısıyla özellik adı kanıtlanabilir biçimde bir modül sabiti. Davranış aynı.

Notlar

Eski korumayı sabitleyen test, kaynak metninde bir grep’ti. Yerine yapısal bir test ve __proto__’yu ham JSON olarak gönderen davranışsal bir test geldi. 3021 → 3022 test.

[1.233.1] — 2026-09-10

Düzeltildi — kılavuz v1.233.0’ın eklediği denetimi hiç anlatmıyordu ve aynı bölüm 200 sürümdür doğru olmayan yönergeler taşıyordu.

Düzeltildi

DOC-1 — «Varsayılanı kullan (…)» girdisi «anahtar ayarlanmadı» durumunu ifade eder; aynı değeri listeden açıkça seçmekle farkı görünmez ve önemlidir. Mevcut ### Behavior listesine üç madde ×17. DOC-2 — bir tablo satırı hiçbir anahtarı adlandırmıyordu: hücrede (server uses default UA) yazıyordu ve v1.19.0’da kaldırılan HH_USER_AGENT’ı anlatıyor, dev.hh.ru’ya kayıt öneriyordu — v1.65.0’dan beri yararsız. Üç eskimiş anma da gitti; sorun giderme satırı silinmedi, yeniden yazıldı: Temmuz 2026’dan beri hh.ru Rus olmayan IP’lere HTTP 451 dönüyor. Anahtar tablosu 45’ten 6’sını listeliyor, oysa başlık bir kayıt defteri vaat ediyor. Bir cümle ×17 onu seçki ilan edip #/config’e yönlendiriyor.

Notlar

Yeni help-recognized-keys.test.mjs, anahtar tablolarının ilk sütununu canlı KNOWN_KEYS ile karşılaştırır. 3018 → 3021 test; yardım 32 H2 / 122 H3 olarak kalıyor.

[1.233.0] — 2026-09-10

Düzeltildi — #/config kaydetme yolunda üç bulgu; CONFIG-3’e v1.232.1’in kendi düzeltmesi yol açtı.

Düzeltildi

CONFIG-3 — tohumlanan değerle çakışan bilinçli bir seçim «dokunulmamış» sayılıp atılıyordu. initial iki kökeni karıştırır: .env’den tohumlama ve defaultValue’dan tohumlama; ikincisinde eşitlik belirsizdir. initial yanına seededFromFile yazılarak düzeltildi. Bir anahtarı kaldırmak «· 0» bildiriyordu, çünkü sunucu yalnızca yazılanı döndürüyordu. Artık removed da dönüyor ve bildirim ikisini birden sayıyor. Açılır liste ayarlanabiliyor ama temizlenemiyordu: 18’inin hiçbirinde boş seçenek yoktu. Artık her biri «Varsayılanı kullan (…)» ile başlıyor. Bir yeni i18n anahtarı ×17.

Notlar

Birim taban çizgisi değişmedi (3018); tarayıcı 111 → 116.

[1.232.1] — 2026-09-10

Düzeltildi — #/config üzerinde Kaydet, kullanıcının hiç dokunmadığı alanları yazıyordu.

Düzeltildi

CONFIG-2. v1.57.1, ayarlanmamış bir denetimi defaultValue ile tohumlar ki alan sunucunun gerçekten kullandığı değeri göstersin; save() ise dirty’yi yalnızca gizli alanlar için sorup diğer tüm alanları her defasında gönderiyordu. Böylece GÖSTERİM için konan değer, kullanıcının seçimiymiş gibi sunucuya gidiyordu: tek bir açılır listeyi değiştirmek 28 anahtar gönderiyor ve kimsenin açmadığı 18 tanesini sabitliyordu. Değişen şey her ayarın durumu: «ayarlanmamış, projenin varsayılanını izle»den «.env’e sabitlenmiş»e.

Notlar

cfg.values ile karşılaştırmak yetmez: ayarlanmamış bir select kendi defaultValue’sunu gösterirken saklanan değer ''’dir. Artık her denetimin tohumlandığı değerle karşılaştırılıyor. Yazılan anahtar sayısı bildirime geri döndü. 105 → 111 tarayıcı testi.

[1.232.0] — 2026-09-09

Düzeltildi — tarayıcı QA geçişinden iki kusur; ikisi de v1.231.5’ten gelmiyor.

Düzeltildi

PROFILE-1 — #/profile tüm sayfayı yana kaydırıyordu. Değer, yalnızca satır içi yazı tipi stilleri taşıyan adsız bir <div>’di; dolayısıyla hesaplanan overflow-wrap normal kalıyordu. Bir LinkedIn URL’si CSS’e geçerli bir kırılma noktası sunmaz, bu yüzden min-content genişliği tüm dizedir; ızgara öğeleri min-width: auto ile bunun altına inmeyi reddeder — kart kendi izini, sonra satırı ve belgeyi patlattı (1280 px’te 23 px gerçek kaydırma). Ortak .card-value sınıfı ve overflow-wrap: anywhere, artı .card-row > * { min-width: 0 } ile düzeltildi. break-word değil anywhere: min-content hesabına yalnızca anywhere katılır. CONFIG-1 — POST /api/config select alanı için her değeri kabul ediyordu. {"LLM_PROVIDER":"not-a-provider"} 200 döndürüp .env’e yazılıyordu; sonrasında hiçbir şey hata vermiyordu, çünkü çözücü sessizce yedeğe düşüyordu. LLM_PROVIDERS zaten env-config.mjs’ten dışa aktarılıyordu — doğrulayıcı ona hiç bakmıyordu.

Notlar

Yalnızca LLM_PROVIDER doğrulanır: modellerin gerçek alanı sağlayıcıya aittir ve sürümlerimiz arasında değişir. Zaten kayıtlı bir değere müsamaha gösterilir; form her kaydetmede tüm gizli olmayan alanları yeniden gönderir. Ayrıca OLLAMA_API_KEY tanımlayıcısı eklendi. 3013 → 3018 test.

[1.231.5] — 2026-09-09

Güvenlik — yedi danışma kapatıldı; biri kritik uzaktan kod çalıştırma. Hiçbir kaynak dosyası değişmedi.

Güvenlik

Dependabot’tan birleştirildi: multer 2.2.0 → 2.3.0 (yüksek — iptal sırasında dosya tanımlayıcı sızıntısıyla hizmet reddi) ve sitede svgo 4.0.2 → 4.1.0 (yüksek ve orta — removeScripts çalıştırılabilir bağlantıları geçiriyordu). Ardından, bu birleştirmelerin tetiklediği yeniden tarama beş tane daha ortaya çıkardı. Etkilenen her aralık mevcut ^ ile zaten karşılanıyordu; dolayısıyla manifest düzenlemesi değil güncelleme gerekti: astro 7.1.0 → 7.3.2 — kritik, AVIF görüntü optimizasyonu üzerinden uzaktan kod çalıştırma (7.2.8’de düzeltildi) ve bir yetkilendirme atlatma (7.2.4); sharp 0.35.3 → 0.35.4 — yüksek, libheif açıkları; ve her iki manifestte js-yaml 4.3.1 → 4.3.2 — yüksek.

Notlar

Burada “yalnızca bağımlılıklar”, “risksiz” demek değil. js-yaml uygulamanın okuduğu her yapılandırmayı ayrıştırır, multer her yüklemeyi kabul eder ve Astro bir minör sürüm ilerledi. Doğrulandı: test:ci 3013/3013, tarayıcı takımı 4/4 ve aynı 86 sayfayı, 17 aynayı üreten tam bir site yeniden yapımı. npm audit: her iki manifestte 0 açık.

[1.231.4] — 2026-09-07

Düzeltildi — v1.231.3 Doctor tıklamasının sonucunu düzeltti, anını değil. Mobilden ve masaüstünden yeniden bildirildi.

Düzeltildi

withSpinner istek uçuştayken düğmeyi hâlâ yeniden yazıyordu. v1.231.3 ona çocuk düğümleri saklayıp finally içinde geri koymayı öğretti ve gerçekten geri geliyorlardı — ama meşguliyet göstergesi yine '⏳ ' + original metniyle replaceChildren çalıştırıyordu. Böylece doctor.mjs çalıştığı sürece 36 px’lik kare ⏳ 🩺Doctor metnini taşıyor ve satırı bozan geniş bir hapa dönüşüyordu; masaüstünde sıkışık bir ⏳🩺Doctor görünüyordu. Öğe çocukları olan bir düğme artık hiç yeniden yazılmıyor: göstergesi .is-loading sınıfı; bu sınıf simgeyi CSS’te kum saatiyle değiştiriyor, dolayısıyla geometri değişemiyor: boşta 36 px, uçuşta 36 px, sonrasında 36 px.

Notlar

Ders koda değil, doğrulamaya dair. v1.231.3’ün kapısı aria-busy temizlenene kadar bekleyip sonra ölçüyordu — yapısı gereği yalnızca finally bloğunun onardığı durumu görebiliyordu. Yeni denetim sözü kendisi açık tutuyor ve uçuşun ortasında örnek alıyor. 3012 → 3013 test.

[1.231.3] — 2026-09-07

Düzeltildi — Doctor’a tıklamak mobilde üst çubuğu bozuyordu. v1.231.2’nin çıktığı gün bir telefondan bildirildi.

Düzeltildi

UI.withSpinner, süslediği düğmenin çocuklarını düzleştiriyordu. Meşguliyet göstergesi textContent üzerinden işliyordu: button.textContent’i sakla, '⏳ ' + original yaz, geri yaz. textContent’e atama bütün çocukları tek bir metin düğümüyle değiştirir — ve v1.231.2 üst çubuktaki her eylemi henüz .btn-ico + .btn-label olarak ayırmış, etiketi max-width: 900px altında gizlemişti. Böylece Doctor’a ilk dokunuş her iki <span>’i kalıcı olarak yok ediyordu: mobil kurallarının eşleşecek bir şeyi kalmıyor, etiket çıplak metin olarak geri geliyor ve 36 px’lik kare, tema anahtarının üstüne binen bir 🩺Doctor hapına dönüşüyordu. Kendiliğinden düzelmiyordu — işaretlemeyi yalnızca sayfa yeniden yüklemesi geri getiriyordu. Düzeltme çocuk düğümlerini saklayıp replaceChildren ile geri koyuyor; yalnızca metin taşıyan düğmeler, yani 24 çağrı yerinin çoğu, tıpatıp eskisi gibi davranıyor.

  • FIND-3 — arama alanı 320 px’lik bir telefonda 8 px’e çökmüştü. Çubuğu tek satıra almak searchbar’ı tek esnek öğe olarak bıraktı; geçen sürümün changelog’u bunu açıkça yazmıştı: «hiçliğe kadar küçülebilir». Küçüldü de: 320 px’te 8 px alan, 340 px’te 28 px — 21 karakterlik bir yer tutucunun tek karakteri. Tıklanabilir ve yazılabilir, ama artık bir alan olarak okunmuyor. Hiçbir min-width bunu çözmez: 320 px’te çubuk 32 px dolgu, 40 px menü ve 162 px eylem taşır; verecek 120 px yoktur. Bu yüzden 420 px altında alan bir büyütecin arkasına gizlenir ve dokununca tüm çubuğa açılır: 320 px’te 182 px, 360 px’te 222 px, 390 px’te 252 px, hiçbir genişlikte taşma olmadan. Düğme tek bir erişilebilir ad korur ve durumu aria-expanded ile bildirir; 🔍/✕ değişimi saf CSS’tir. 420 px üstünde hiçbir şey değişmez. Canlı yapıya karşı yapılan tarayıcı regresyon geçişinde bulundu.

Notlar

Bu, v1.231.2’de not edilen applyI18n() tuzağıyla aynı kusur sınıfı — artık öğe çocukları olan bir öğeye textContent atayan kod — yalnızca başka bir çağırandan geliniyor. Ders genelleşiyor: bir öğenin içeriğini çocuk <span>’lere bölmek, o öğe üzerindeki mevcut her textContent yazıcısını gizli bir hataya dönüştürür. İki kez kilitlendi: gerçek withSpinner üzerinde node:vm ve 320 px’te gerçek bir tarayıcıda tıklama. İkisinin de eski kodda düştüğü doğrulandı. 3009 → 3012 test.

[1.231.2] — 2026-09-06

Düzeltildi — mobil üst çubuk iki satıra bölünüyordu, sunucu daha eski bir üst projeyle çalışıyordu ve cvstart.ru yönlendirmesi zaten bir dil adı taşıyan her yolda 404 veriyordu.

Düzeltildi

  • Mobil üst çubuk yeniden tek satır, eylemler yalnızca simge. Eylem düğmeleri tam genişlikte ikinci bir satıra zorlanıyordu: telefonda [☰ · arama] üstte, [🔔 🌙 Doctor Scan'i aç] altta — kendi satırında iki geniş hap. Artık zil ve tema düğmesinin yanında 36 px kare (🩺 / ⚡) ve 320 px’te her şey tek satıra sığıyor. Göz kararı değil, ölçüldü: belge genişliği 320, 360, 390 ve 430 px’te ve düğmelerin eskiden arama alanının üstüne bindiği 560–760 px bandının tamamında görüntü alanına eşit. Dil artık mobil yerleşimi hiç etkilemiyor, çünkü etiket gizli ve düğme sabit bir kare; 900 px üstünde etiketler değişmeden geri geliyor.
  • Sunucu, sürüm 1.32.0’a göre derlenmiş olmasına rağmen üst proje 1.31.0 ile çalışıyordu. Üretim sunucusu üzerinde /api/health parentVersion: 1.31.0 bildiriyordu. 95 çalışma dosyası eşitlendi, iki tanesi kaldırıldı. Canlı yüzeyde tarayıcı QA’sıyla bulundu.
  • cvstart.ru her yolun başına /ru/ ekliyordu, orada ne olduğuna bakmadan. /ru/help /ru/ru/help oluyordu, /en/help ise /ru/en/help; ikisi de 404. Birincisi ana siteden bir adresi kopyalayınca oluşuyor; ikincisi İngilizce konuşan ziyaretçiyi İngilizce sürümden tamamen dışarıda bırakıyordu. Artık 16 dil önekinden birini zaten taşıyan yol olduğu gibi geçiyor, en kaldırılıyor (İngilizce kökte duruyor), gerisi yine /ru/ alıyor.

Değiştirildi

  • 98 geçersiz kalmış QA istemi qa/archive/superseded-prompts/ altına taşındı. qa/README.md, v1.137.0’dan beri üst düzeyde yalnızca güncel sürümün isteminin kaldığını belgeliyor — kural 95 sürüm boyunca uygulanmadı.
  • Beş prompt daha üst seviyeden ayrıldı — kendilerini güncel ilan ediyorlardı, değillerdi. REGRESSION-FINAL.md kendini «tek yetkili, sürümden bağımsız regresyon promptu» diye adlandırıyordu; oysa §§11–15’i kapanmış beş döngü defteri (v1.55.x → v1.59.7) ve beyan ettiği yardım temeli 16 dilde 28 H2 / 103 H3 iken bugün 32 / 122 ve 17: onu izleyen bir QA aracı §9’da daha ilk adımda düşerdi. QA-REGRESSION-PROMPT.md sürümsüz bir ada ve v1.226.0 içeriğine sahipti. QA-REGRESSION-PROMPT-v1.76.0-FULL.md 155 sürüm geriye sabitlenmişti, REGRESSION-PROMPT-FINAL.md v1.58.52 → v1.59.10 döngüsünü kapatır ve QA-FULL-REGRESSION.md hepsini v1.131.1 temelinde yineliyordu. Onlarla birlikte PARENT-SYNC-WORKLIST-v1.26.0.md de gitti (üst proje artık 1.32.0) ve tarihli UX-AUDIT-2026-07-06.md reports/ altına taşındı. Geriye, kendi temelleri v1.231.2 gerçek değerlerine güncellenmiş dört sürücü kaldı. qa/README.md var olan klasörü anlatacak biçimde yeniden yazıldı.

Notlar

  • İki özgüllük tuzağı artık app.css içinde açıklanıyor: masaüstü kuralları max-width: 900px bloğundan daha aşağıda tanımlı, bu yüzden eşit özgüllükte onlar kazanıyordu — mobil gap sessizce 24 px kaldı (320 px’i taşıran buydu) ve simge gizli kaldı (boş kare düğmeler).
  • applyI18n() el.textContent atadığı için i18n anahtarı iç <span>’e taşındı; düğmede kalsaydı her dil değişiminde simgeyi silerdi.
  • Üst projenin ilk rsync’i yerelde artık bulunmayan bir dosyada yarıda kesildi ve yine de başarı bildirdi. Üst proje dağıtımları artık çıkış koduyla değil, sağlama toplamıyla doğrulanıyor.

[1.231.1] — 2026-09-06

Düzeltildi — v1.231.0’ın sayaç taraması tüm bağlantılardaki hesap adını değiştirdi.

Düzeltildi

  • Her Fighter90 bağlantısı Fighter92 oldu. v1.231.0’daki kaynak sayacı taraması, 290 ve 901’i doğru şekilde atlayan ama Fighter90 içindeki 90 ile eşleşen bir rakam sınırı koruması altında 90’ı 92 ile değiştirdi. 17 README’nin tamamında, 17 yardım paketinin tamamında ve sitenin yardım aynalarında 562 bağlantı, artı wiki’de 138 tanesi, var olmayan bir hesabı gösteriyordu. Eksik görsel sayesinde bir kullanıcı fark etti.
  • Beş tarihsel sürüm göndermesi kaydı. Aynı sürümdeki 85 → 87 taraması v1.85.0’ı v1.87.0 yaptı ve hiç çıkmamış bir sürüm uydurdu.

Notlar

  • Rakam sınırı yeterli değil: bir sayıyı komşu rakamlardan korur, bir tanımlayıcının ya da bir sürüm dizesinin parçası olmaktan değil. Sayaçların kendisi doğru: 92 kaynak, 87 EN bağdaştırıcı, 3009 test.
  • Üst depo etkilenmedi.

[1.231.0] — 2026-09-05

Eklendi — üst career-ops v1.32.0’dan iki tarama kaynağı (Collage, Telegram katı), Gem’in REST kipi ve taşımanın üst projenin kendi kodunda ortaya çıkardığı bir kusur.

Eklendi

  • İki yeni kaynak, 90 → 92 (87 EN + 5 RU), ALL_ADAPTERS 85 → 87. İkisi de belirteçsiz.
    • Collage (provider: collage) — Collage HR’ın açık iş sitesi API’si. Yol parçası, kiracının kendi seçtiği site adresidir, şirket adından türetilmiş bir slug değil: api:’den ya da bir secure.collage.co/jobs/<adres> URL’sinden okunur ve asla tahmin edilmez — tahmin edilen bir adres başkasının panosunu tarardı.
    • Telegram (katı) (provider: telegram-channel) — mevcut telegram kaynağının okuduğu aynı t.me/s/<kanal> önizlemelerini okur, ama ters takası yapar: bir gönderi ancak bir işveren adı verip bir ilan sayfasına bağlanıyorsa satır olur. Derlemeler, işvereni gizli gönderiler ve yalnızca iletişim içeren gönderiler elenir. Kapsam bilinçli olarak düşük — yukarı akışta gönderilerin %32-77’sinin geçtiği ölçüldü — ama her satır gerçek bir işveren ve gerçek bir bağlantı taşır. İkisi de üst projedeki gibi birlikte sunulur.
  • Gem’e isteğe bağlı bir REST kipi eklendi, GraphQL yolunun yanına (api: https://api.gem.com/job_board/v0/<board>/job_posts). Asla bir pano kimliğinden türetilmez ve GraphQL yolu varsayılan kalır. #3783’ten taşındı.

Düzeltildi

  • telegram-channel’ın konum süzgeci Kiril harflerini göremiyor ve şehirleri işveren diye adlandırıyordu. Üst projedeki LOCATIONISH_RE, yalnızca ASCII için çalışan ve Kiril harflerinin yanında hiç tetiklenmeyen \b sınırını kullanıyordu: içindeki tüm Rusça seçenekler erişilemezdi ve Senior Engineer | Москва “Москва”yı işveren olarak döndürüyordu. Bu, tüm atıf politikasının önlemek için var olduğu yanlış-alan-gerçek-yerine ikamesinin ta kendisi ve sağlayıcının asıl kitlesini vuruyordu. web-ui taşıması Unicode denetimleri kullanıyor; üst projenin bir sabit aşağıda ROLE_WORD_RE içinde zaten yaptığı şey. ASCII biçiminde başarısız olan bir testle sabitlendi. Yukarı akışta henüz düzeltilmedi.

Notlar

  • Üst projenin Workday faset kurtarma çalışması (#3851, #3874) taşıma gerektirmedi — web-ui Workday’i hiç sayfalamıyor, offset: 0 ile tek bir POST.
  • providers/_types.js yalnızca belgelerde değişti.
  • Testler: 2962 → 3009 (+47).

[1.230.0] — 2026-09-05

Değişti — üst career-ops v1.32.0’dan üç sağlayıcı düzeltmesi ve taşımanın kendisinin ortaya çıkardığı bir kusur.

Eklendi

  • Welcome to the Jungle sunucu tarafında bir Algolia filters ifadesi kabul ediyor (wttj: { filters: "offices.country_code:FR AND contract_type:full_time" }). Tek başına bir anahtar sözcük küresel bir panoyu daraltmaz: hangi max_hits sonucun geleceğine tarayıcının filtreleri değil, Algolia’nın alaka sıralaması karar verir — bizimkiler sonradan, gelmiş olanın üzerinde çalışır; dolayısıyla üst sınırın ötesindeki her şey, ne kadar iyi eşleşirse eşleşsin görünmezdir. Bir filtre sonuçları yeniden sıralamak yerine kümeyi küçültür, bu yüzden sorgu başına sınır 200’den 1000’e çıkar. Filtre varken queries isteğe bağlı hale gelir: boş sorgu “filtreden geçen her şey” demektir. Üst projeden #3757 taşındı.

Düzeltildi

  • Radancy, bir kiracı yalnızca kendi başlığının iddia ettiğinden daha az ilan sunduğunda artık “truncated” uyarısı vermiyor. Üst proje data-total-results değerini dokuz gerçek kiracıyla karşılaştırdı: beşi tuttu, ancak dördü — biri küçük, biri devasa — ilan edilenden %10–56 daha az benzersiz ilan verdi, hem de tek bir yinelenen satır olmadan. Başlık, kiracının kendi arama dizininin gerçekte sunduğunu abartıyor; bu yüzden biriken sayımı onunla karşılaştırmak panoların çoğunda yanlış alarm üretiyordu. Uyarı artık yalnızca yürüyüşü bizim kendi max_jobs/max_pages değerimiz durdurduğunda çıkıyor — çağıranın üzerinde işlem yapabileceği tek durum; totalResults bağlam olarak iletide kalıyor ve asla karar vermiyor. #3839’dan taşındı.
  • Radancy her JSON parça isteğinde önbelleği atlıyor. Bu yolun önündeki bir önbellek katmanı bazı kiracılarda eski yanıtları tekrarlıyor: aynı ilan sayfalar sonra yeniden çıkarken bir başkası hiç sunulmuyor — yukarı akışta dokuzda dokuz kez yeniden üretildi. Cache-Control/Pragma başlıkları hiçbir şeyi değiştirmedi; istek başına rastgele bir parametre sorunu çözdü. Bu parametre çağrı başına benzersiz olmalı, asla sayfa numarasından türetilmemeli: belirlenimci bir parametre önbelleğe yine kararlı bir anahtar, dolayısıyla aynı kararlı ve yanlış eşlemeyi verir. #3839’dan taşındı.
  • Greenhouse ofis listeleri belirlenimci sıradadır. Greenhouse yanıtlar arasında offices[] sırasını garanti etmez ve /offices ağacından toplanan küme kendi gezinme sırasını izler. İkisi de ilanın location alanına ulaşır; bu yüzden ofislerini yeniden sıralayan bir pano o dizgiyi yeniden yazıyor ve değişmemiş bir ilan yeni gibi okunuyordu. Üst proje kümeyi düzeltti (#3839); web-ui’de aynı kusurun üst projede bulunmayan ikinci bir örneği vardı — ilanın kendi konumu yokken devreye giren offices[0] yedeği — ve artık ikisi de sıralanıyor.

Notlar

  • Üst projedeki iCIMS düzeltmesi (#3728) taşıma gerektirmedi. O, ayrıntı sayfasının JSON-LD’sindeki her jobLocation girdisini okur; çünkü bazı kiracılar gerçek adresten önce tamamen UNAVAILABLE bir girdi yayınlar. web-ui’nin iCIMS’i konumu liste sayfasının HTML’inden alır ve hiçbir zaman ayrıntı sayfası açmaz.
  • _http.mjs değişikliği taşıma gerektirmedi. isRefusedRedirectError’ı web-ui’de bulunmayan ikinci bir tüketici için ayırır; isRetryableError’ın davranışı değişmez.
  • Konum duyarlı yinelenen ayıklama (#3751) yansıtılmaz — üst CLI’nin scan.mjs hattında yaşar.
  • Kayıt defteri değişmedi: 90 kaynak (85 EN + 5 RU). Testler: 2956 → 2962 (+6).

[1.229.0] — 2026-09-03

Eklendi — üst proje career-ops v1.31.0’dan dört tarama kaynağı: Built In, Feishu Jobs, Garena ve MokaHR.

Eklendi

  • Dört yeni kaynak, 86 → 90 (85 EN + 5 RU), ALL_ADAPTERS 81 → 85, dördü de jetonsuz. Built In ABD teknoloji panosunun dokuz pazarını kapsar ve varsayılan sorgu taşımaz: queries: ve categories: olmayan bir kayıt hiçbir şey taramaz ve bunu söyler — paylaşılan bir kaynak kimsenin arama sözcüklerini taşımamalı; listede olmayan bir pazar reddedilir, sessizce ulusal panoyla değiştirilmez. Feishu Jobs tam olarak iki ana bilgisayar biçimi kabul eder ve bunlar ilan sayfasına farklı yollar kullanır. Garena tek şirkettir: office bağlantıyı biçimlendirir, listeyi değil. MokaHR şifreli yanıt döndürür (anahtarı yanında gelen AES-128-CBC zarfı) — güvenlik değil gizleme, ama çözmeden hiçbir şey okunmaz.

Düzeltildi

  • htmlToText metne yarım bir etiket açıcısını sızdırabiliyordu. safe &lt;img src=x onerror=1 şöyle çıkıyordu: safe <img src=x onerror=1. Artık her çözümlemeyi bir temizleme izliyor ve sondaki açıcı köşeli işaretini yitiriyor. Üst projeden portlandı (#3491).

Notlar

  • Üst projenin Workday düzeltmesinden hiçbir şey portlanmadı. O düzeltme, arka ucu sayfalamayı 2000. konumda kilitleyen kiracıları kurtarır — web-ui Workday’i hiç sayfalamıyor (offset: 0’da tek POST, 100 satır).
  • verify-cv-facts ve merge-tracker düzeltmeleri port gerektirmedi: web-ui bu betikleri üst projenin checkout’undan çalıştırır.
  • Testler: 2909 → 2956 (+47).

[1.228.5] — 2026-08-30

Düzeltildi — bildirilen sürüm diskteki dosyayı tarif ediyordu, çalışan kodu değil.

Düzeltildi

  • /api/health her istekte package.json’ı yeniden okuyordu, dolayısıyla eskimiş bir süreç çalıştırmadığı bir sürümü bildiriyordu. QA, version: 1.228.4 yanıtı verirken 1.228.3’te eklenen /api/ping için 404 döndüren yerel bir örnek buldu: dağıtımdan önce başlatılmış, eski kodu sunuyor ve yeni dosyanın sürümünü bildiriyordu. Dosyaları kopyalayıp asla yeniden başlatmayan bir dağıtım tam olarak böyle başarılı görünür: bir operatörün baktığı tek dizge, sorunu göremeyen dizgedir. v1.228.1’deki sembolik bağla aynı sınıf — rsync aktarımın ortasında durup yine de başarı bildiriyordu.

    Sürüm artık modül yüklenirken yakalanıyor ve çalışan kodu tarif ediyor. Eskimiş bir süreç eski sürümü bildirir — gerçeği, ilk istekte görünür biçimde. parentVersion istek başına kalmaya devam ediyor: üst projenin checkout’unu tarif eder; bu süreç onu yüklemez ve çalışan bir sunucunun altında meşru olarak değişebilir.

[1.228.4] — 2026-08-30

Düzeltildi — kimlik doğrulaması olmayan canlılık probu her istekte disk işi yapıyordu.

Düzeltildi

  • GET /api/ping her vuruşta package.json okuyup ayrıştırıyordu. Kimlik bilgisi olmadan erişilebilen tek uç nokta olduğundan, istek başına bir disk okuması artı JSON ayrıştırması herkese uzatılmış bir hizmet reddi kaldıracıdır — CodeQL bunu hız sınırlaması eksikliği olarak işaretledi. Sürüm artık rota kaydında bir kez okunuyor; yeniden başlatmadan zaten değişemez, dolayısıyla işleyici hiç G/Ç yapmıyor. Hız sınırlaması hasarı sınırlardı; işi kaldırmak kaldıracı kaldırır.
  • Profil sahibinin gerçek adının loopback dışında maskelenmesi artık bir testle sabitlendi. /api/health bunu zaten hidden ile değiştiriyordu — ama yalnızca o satır hidden ?? value koruyucusunu proje köküyle paylaştığı için. Bunu hiçbir şey sınamıyordu; satıra kendi değerini veren bir düzenleme, gerçek bir kişinin adını fark edilmeden yerel ağa sızdırırdı.

[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

Eklendi — tarama kaynağı olarak Telegram kanalları ve /api/scan-results için sayfalı sorgu kipi.

Eklendi

  • Telegram kanalları artık taranabilir bir kaynak. portals.yml içindeki telegram_channels: bloğu onları listeler; her biri herkese açık https://t.me/s/<kanal> önizlemesinden okunur. Kayıt defteri: 85 → 86 kaynak (81 EN + 5 RU), ALL_ADAPTERS 80 → 81. Telegram RSS yayımlamaz ve Bot API, botun yönetmediği bir kanalı okuyamaz — iki bariz yol da kapalı. /s/ önizlemesi sunucuda üretilmiş düz HTML’dir: oturum yok, JS yok, çerez yok. 16 kanalda doğrulandı: 15’i çıplak bir GET’te 20’şer gönderi döndürdü.
  • GET /api/scan-results sayfalı sorgu kipi kazandı. ?q=<metin>&limit=50[&region=ru|en][&set=filtered|fresh][&offset=N] { total, returned, offset, limit, set, rows } döndürür; total sayfalamadan ÖNCEKİ sayıdır. Parametresiz haliyle rota yine tüm anlık görüntüyü döndürür — #/scan tablosu o biçime bağlıdır.

Düzeltildi

  • Telegram asistanı verinin bir kısmıyla yanıt veriyordu. Becerisi zaten /api/scan-results’ı gösteriyordu, ama rota yalnızca tüm anlık görüntüyü döndürebiliyordu — gerçek makinede yaklaşık 2 MB — ki bu bir ajanın bağlamına sığmaz. «Tüm Product Manager’ları bul» isteğine, anlık görüntüde yüzlercesi varken 9 eşleşme bildirdi ve «sınırlı bir yerel dizinle çalıştığını» söyledi. Doğruydu: uç noktayı görüyor ama sindiremiyordu. Sayfalı kiple aynı soru 2 KB tutuyor ve dürüst bir total döndürüyor. Beceri de yeniden yazıldı: yeni gönderileri özetlemeyi istiyordu, yani filtered yerine fresh’i işaret ediyordu.

Notlar

  • Kanal gönderisi düzyazıdır, iş kaydı değil. Yapılandırılmış alan yok: başlık ilk anlamlı satırdan, şirket/konum/ücret açık etiketlerden alınır. Gerçek ilanları reklam ve derlemelerden ayırmak mevcut title_filter’a bırakılmıştır — diğer kaynaklar için zaten ayarlanmış olana. Bunlar ipucudur, liste değil.
  • Şirket asla tahmin edilmez. Etiket yoksa satır kanala atfedilir (@rabotaphp): yanlış bir işveren izleyiciye gerçek olarak girer.
  • Boş ayrıştırma bir hatadır, «ilan yok» değil. t.me gizli veya var olmayan bir kanala yönlendirmeyle yanıt verir; sıfır satır döndürmek sakin bir gün gibi okunur ve yapılandırmadaki yazım hatasını sonsuza dek gizler. jobGeeks tam da bunu yapar (HTTP 302) ve bilinçli olarak yapılandırılmadı.
  • Uzaktan çalışma tespiti \b yerine Unicode sözcük sınırı kullanır; \b yalnızca ASCII bilir — v1.227.3’te başlık filtresinin düştüğü tuzağın aynısı, burada yayından önce bir testle yakalandı.
  • 15 kanal yapılandırıldı ve canlı doğrulandı: 299 gönderi, 15/15 kanal. 30 yeni test. Testler: 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

Düzeltildi — bölgesel tarama sunucunun belleğini tüketiyordu ve bir Playwright takımı kendi sökümünde kararsız biçimde düşüyordu.

Düzeltildi

  • Bölgesel tarama sunucuyu OOM ile öldürüyordu. ru-scanner, tüm sorguların tüm ham sonuçlarını biriktirip yinelenenleri ayıklamayı ve süzmeyi ancak en sonda yapıyordu. Sorgu listesi bilerek yakın eşanlamlılarla dolu (Golang, Go разработчик, Golang разработчик, Senior Go…), yani aynı ilan her sorguda bir kez dönüyor ve dizi benzersiz sayının katlarını tutuyordu — üstelik ilan nesnesinin büyük kısmını oluşturan ve süzgeçlerin neredeyse tümünü attığı açıklamalarla birlikte. Ölçüm: 21 sorgulu gerçek bir koşuda 742 MB yığın. Sunucu Node yığınını 490 MB ile sınırlıyor (V8 bunu makinenin 956 MB RAM’ine göre belirliyor), bu yüzden tarama servisi FATAL ERROR: Reached heap limit ile deviriyordu — bir günde dört kez. Artık ayıklama ve süzme her sorguda yapılıyor; aynı koşu 177 MB’a indi, %76 azalma. Raporlanan sayılar değişmedi: benzersiz toplamı URL dizgilerinden oluşan bir Set taşıyor.
  • net::ERR_SOCKET_NOT_CONNECTED CI’ı rastgele düşürüyordu. Üç Playwright takımı, konsol hatası olmadığını doğrulamadan önce süren istekleri durdurmak için window.stop() çağırır. Chromium bu tek kasıtlı eylemi soketin durumuna göre üç farklı adla bildirir: iptalde ERR_ABORTED, yoldayken ERR_EMPTY_RESPONSE, soket çoktan gitmişse ERR_SOCKET_NOT_CONNECTED. Ortak filtre yalnızca ilk ikisini biliyordu. tr yerel taramasında ortaya çıktı; aynı çağrıyı yapan playwright-forms ve playwright-smoke da tek şanssız koşum uzaktaydı.

Notlar

  • Neden ancak şimdi bozuldu. Ürün müdürü aramaları eklenince liste 14’ten 21 sorguya çıktı. Eski uygulamanın belleği toplam sonuç sayısıyla ölçekleniyordu, dolayısıyla %50 daha fazla sorgu makinenin tavanını aştı.
  • Ayıklama değişikliği davranışı korur ve bu iddia değil, test edilmiştir. tests/ru-scanner-dedup-order.test.mjs zor yönü sabitler — süzgeçlerden geçemeyen sonraki bir yineleme, geçmiş olan öncekini dışarı atmalıdır — ve eski uygulamaya karşı 200 rastgele denklik denetimi koşar.
  • Konsol süzgeci dar kalıyor. Yalnızca iptal edilmiş istek ailesi zararsızdır; reddedilen bağlantı, DNS hatası, sıfırlama, her 5xx ve yakalanmamış JS istisnaları hâlâ savı düşürür.
  • İki hipotez gönderilmek yerine sınandı ve elendi: Caddy zaman aşımı (yapılandırma temiz, SSE için flush_interval -1 doğru) ve Node’un varsayılan 5 dakikalık requestTimeout değeri (küçültülmüş bir yeniden üretim, uzun bir akış yanıtını kesmediğini gösterdi). Asıl kanıt, günlükteki Reached heap limit idi. Testler: 2860 → 2865.

[1.227.4] — 2026-08-29

Düzeltildi — word: / stem: content_filter tarafından hâlâ yok sayılıyordu; v1.227.3 yalnızca başlık filtresini düzeltmişti.

Düzeltildi

  • content_filter önekleri dikkate almıyordu. v1.227.3, title_filter’a üst projenin word: / stem: öneklerini öğretti ama content_filter’ı kendi ham lower.includes(k) çağrısıyla bıraktı; dolayısıyla orada önekli bir girdi hâlâ birebir metin olan "word:java" ile eşleniyordu — aynı sessiz no-op, bir filtre ötede. content_filter ilanın AÇIKLAMASINI okur ve varsayılanı hep düz alt dize olmuştur: bu yüzden çıplak bir olumsuz java, yalnızca „JavaScript“ten söz eden her ilanı eler; önek ise tek bir girdiyi bu varsayılandan çıkarma yoludur. Üst projenin compileContentKeyword işlevi aktarıldı: aynı önek düzeneğini paylaşır ama kısa anahtar kelimeleri bilinçli olarak sabitlemez — başlık filtresi 2–3 harfli kısaltmaları sabitler çünkü „Coordinator“ içindeki „COO“ her zaman yanlıştır; oysa bir düzyazı paragrafındaki kısa dizi çoğu kez kasıtlıdır (aws, gcp, sql, go).

Notlar

  • v1.227.3 PR’sinin yapay zekâ incelemesinde bulundu; inceleme, kodun kendi yorumunun iddia ettiğini karşılamadığını fark etti — yorumda „title_filter / content_filter“ yazıyordu ama yalnızca başlık yolu bağlıydı. Yorum artık açıkça ayırıyor: önekleri iki filtre de tanır, kısaltmaları yalnızca başlık filtresi sabitler.
  • Yine o incelemeden doğrulandı ve değişmedi: 2–3 harfli kısaltma kuralını \b yerine Unicode sınırına taşımak ASCII’de birebir aynı davranır ve yalnızca olması gereken yerde daha katıdır — COO_lead ve coo1 korunmaya devam eder (alt çizgi ve rakam her ikisinde de sözcük karakteridir), Coordinator korunur, „Директор COO“ ve „VP «Продукт»“ doğru biçimde elenir. 14 sınır durumu denetlendi.
  • Öneksiz content_filter girdileri önceki eşleşmesini bayt bayt korur, boş veya eksik bir açıklama yine geçer ve içi boş bir word: / stem: her şeyle değil hiçbir şeyle eşleşir. tests/content-filter.test.mjs içinde 6 yeni durum. Testler: 2852 → 2858.

[1.227.3] — 2026-08-29

Düzeltildi — başlık filtresindeki word: / stem: önekleri sessizce yok sayılıyor, o filtre satırlarını etkisiz bırakıyordu.

Düzeltildi

  • web-ui, üst projenin word: / stem: öneklerini uygulamıyordu. title_filter (ve content_filter) varsayılan olarak büyük/küçük harf duyarsız alt dize eşleşmesi yapar; bu yüzden çıplak bir olumsuz intern girdisi „International Product Manager“ ve „Internal Tools Engineer“ başlıklarını da eler. Bu varsayılanı tersine çevirmek yapılandırılmış her kurulumu bozacağından, üst proje kesinliği girdi başına isteğe bağlı yaptı: word:intern yalnızca tam sözcüğü, stem:agent ise bir sözcüğün başını eşler ve devam edebilir („Agentforce“ ile „Reagents“ı ayırır). web-ui’de ikisi de yoktu; girdiyi birebir metin olan "word:intern" şeklinde eşliyordu — böyle bir dizi hiçbir ilan başlığında geçmez. Satır sessiz bir no-op’a dönüştü: aynı portals.yml CLI’da doğru süzerken burada hiç süzmüyordu, dolayısıyla dışlanan her staj ilanı yine #/scan tablosuna ulaşıyordu. Üst projenin title-keywords.mjs dosyasından aktarıldı; yalnızca ASCII bilen ve aksanlı ya da Kiril başlıklarda sözcük ortasında eşleşen \b yerine Unicode farkında sözcük sınırı (\p{L}\p{M}\p{N}_) dahil.

Notlar

  • Gerçek bir portals.yml incelenirken bulundu; oraya word:intern tam da çıplak intern girdisi „International Product Manager“ı elemesin diye yeni eklenmişti. Önek CLI’da çalışıyordu; web-ui sessizce tüm staj ilanlarını tutuyordu. Artık davranış aynı.
  • Varsayılanlar değişmedi. Öneksiz bir anahtar kelime önceki eşleşmesini korur: öbekler ve harf dışı karakter içeren her şey (.NET, SAP , L&D) alt dize, 2–3 harfli kısaltmalar sözcük sınırına bağlı. İçi boş word: / stem: yazım hatası sayılır ve hiçbir şeyle eşleşmez — olumsuz olarak boş bir desen her başlıkla eşleşir ve tek bir başıboş iki nokta yüzünden tüm taramayı geçersiz kılardı.
  • 2–3 harfli kısaltma kuralı da aynı Unicode sınırını kullanıyor: önceden \b kullanıyordu, bu yüzden ASCII dışı başlıklarda coo ile word:coo ayrışıyordu — tek kuralın iki yazımı.
  • tests/title-filter.test.mjs içinde 6 yeni durum. Testler: 2846 → 2852.

[1.227.2] — 2026-08-29

Düzeltildi — dar telefonlarda #/config yana kayıyordu.

Düzeltildi

  • MOBILE-1: #/config ≤ 352 px görünüm alanlarında yatay taşıyordu. Her select alanı satır içi bir min-width: 300px taşıyordu. Satır içi stil stil sayfasını yener, dolayısıyla denetim kabıyla birlikte küçülemiyordu: 320 px görünüm alanında select’in sağ kenarı 353 px’e düşüyor, sayfada yatay kaydırma oluşuyor ve denetimler sağ kenarın dışına itiliyordu. 18 sağlayıcı/model select’inin tamamı etkileniyordu (cfg-llm-provider ve tüm cfg-*-model). Artık min-width: min(300px, 100%) + max-width: 100%; rahat 300 px yalnızca yer varsa uygulanıyor. Eşikteki ve altındaki cihazlar: iPhone SE (1. nesil, 320 px), eski Android’ler, Galaxy Fold dış ekranı.

Notlar

  • Önceki tüm mobil geçişlerin bunu neden kaçırdığı. 360 px ve 375 px taşmayı gizlemeye tam yetecek paya sahip ve Playwright takımları 1280 px genişliğinde bir pencerede koşuyor. CI’da 375 px’ten dar bir görünüm alanı hiç ölçülmemişti. Yeni tests/playwright-narrow-viewport.mjs form taşıyan rotaları 320 px’te tarıyor ve herhangi bir yatay taşmada başarısız oluyor; mesajda en geniş öğeyi adlandırıyor. İkinci durum, hiçbir #/config select’inin görünüm alanını aşmadığını sabitliyor. Önce hatayı yeniden ürettiği doğrulandı (scrollWidth 353 > clientWidth 320, sağ kenarı 353 olan 18 select). Playwright: 99 → 101.
  • Bilinen ve bilinçli olarak henüz kapı altında değil: 280 px (Galaxy Fold dış ekranı) hâlâ ~5 px taşıyor, ama nedeni farklı — yapılandırma kartının <details> bloklarındaki uzun içerik ve 280 px görünüm alanına karşı 256 px’lik kenar çubuğu; bu sürümün düzelttiği satır içi min-width değil. Yaygın hiçbir telefonun bildirmediği bir genişliğe göre yeniden akıtmak ayrı bir iş; takımın WIDTHS listesi buna hazır.
  • v1.227.1 QA istemi de düzeltildi: takip rotasını #/modes/followup olarak adlandırıyordu. Mode sayfaları çıplak slug ile kaydolur (Router.register(cfg.slug)), dolayısıyla rota #/followup’tır ve #/modes/followup doğru şekilde 404 verir. Yalnızca belge.
  • Birim takımı 2846’da değişmedi (yeni kapsam tarayıcı düzeyinde).

[1.227.1] — 2026-08-29

Düzeltildi — yardımdaki kaynak dökümü kendisiyle tutmuyordu ve GitHub afişi uygulamada ham işaretleme olarak basılıyordu.

Düzeltildi

  • §17 toplamı ve dökümü birbirini tutmuyordu. Tüm yardım paketleri „server/lib/sources/ kaydı 85 adaptör içerir — 78 İngilizce + 5 Rusça“ diyordu. 78 + 5 = 83, 85 değil; ja/ko’da sapma 77’ye (= 82) kadar gitmişti. Her yeni kaynak toplamı yükseltip terimi olduğu gibi bıraktığı için iki sayı birkaç sürümdür ayrışıyordu. Döküm artık 17 dilin tamamında 80 EN + 5 RU. Bu görsellikten fazlası: docs/help/<lang>.md, „Ask the docs“un dayandığı TEK derlem; dolayısıyla kaç kaynak desteklendiğini soran kullanıcı tek bir cümleden birbiriyle çelişen iki sayı alıyordu.
  • Aynı cümle eskimiş bir sürüm çıpası tutuyordu. „v1.213.0 itibarıyla kayıt …“ 16 dilde hayatta kalırken sayaç iki kez değişti (v1.219.0’da 83, v1.226.0’da 85). Çıpa v1.210.1’de elle bir kez onarılmış ve yeniden kaymıştı. Sürümsüz bir ifade lehine kaldırıldı — sayacın kendisi canlı kayda karşı doğrulanıyor ve eskiyemez.
  • Sağlayıcı afişi #/help başında kaçışlanmış işaretleme olarak basılıyordu. v1.225.0/v1.225.1, onun „UI.md() tarafından uygulamada kaldırıldığını (görsel desteği yok)“ kaydetmişti. Bu iki farklı şeyi karıştırıyor: UI.md() önce kaçışlar — herhangi bir markdown dönüşümünden önce kaynağın her baytını kaçışlar; bu doğru XSS sınırıdır ama kaldırmanın tam tersidir. Kimse afişi kaldırmıyordu çünkü kimse denemiyordu ve 17 dilin tamamı #/helpi 268 karakterlik düz <p align="center"><img src="https://… ile açıyordu. Yeni ortak giriş (server/lib/help-markdown.mjs::stripGithubOnlyBlocks) okuma sırasında tek başına duran HTML görsel bloklarını atıyor — hem GET /api/help/:lang hem de docs-assistant derlemi için. Dosyalarda afiş kalıyor, dolayısıyla GitHub vitrini yine görünüyor.
  • Kadans panosundaki „#“ sütunu v1.117.0’dan beri boştu. entry.appNum okuyordu; oysa followup-cadence.mjs num yayıyor — appNum yükte hiç var olmadı. Artık ikisi de okunuyor. v1.227.0’daki „Next up“ satırı aynı hatayı devralmıştı, birlikte düzeltildi.

Notlar

  • Dördü de kendilerini kollayan bir şey olmadığı için gözden kaçtı. Yardım kapıları (canonical-docs-coverage, help-ui, help-ru-config-section) BAŞLIK sayar — 32 H2 / 121 H3 — ve hiçbir test bir paragrafın içindeki sayıyı okumamış, yardım girişinin gerçekte ne sunduğuna bakmamıştı. İki yeni takım bunu kapatıyor: tests/help-source-counts.test.mjs (belirtilen toplam SOURCES.lengthe eşit; terimler canlı EN/RU bölünmesine eşit ve toplamı veriyor; paragraf sürüm sabitlemiyor) ve tests/help-banner-strip.test.mjs (afiş GitHub için diskte kalır, süzmeden asla sağ çıkmaz, her paketin ilk render satırı başlığıdır, süzme dar kalır ve iki tüketici de oradan geçer). İkisinin de commit öncesi tam bu hatalara karşı kırmızı düştüğü doğrulandı. Test paketi: 2837 → 2846.
  • Kayıt, tarayıcı veya rota sözleşmelerinde değişiklik yok; kaynaklar 85 (80 EN + 5 RU), ALL_ADAPTERS 80 olarak kalıyor.

[1.227.0] — 2026-08-28

Eklendi — SEEK Hong Kong (JobsDB), takipler için yalnızca-zamanı-gelenler süzgeci ve gizli işverenlerin kendilerini sunan ajansı göstermesi.

Eklendi

  • Mevcut Jobstreet/SEEK kaynağı üzerinden JobsDB Hong Kong. Hong Kong JobsDB markasıyla işliyor ama aynı v5 uç noktasının arkasındaki aynı SEEK platformunda duruyor; bu yüzden ayrı bir kaynağa gerek yok — host beyaz listesine hk.jobsdb.com ve siteKey: HK-Main yeterli. Kayıt defteri değişmiyor: 85 kaynak (80 EN + 5 RU) ve ALL_ADAPTERS 80 — bu, mevcut bir adaptör üzerindeki yeni bir PAZAR, yeni bir adaptör değil.
  • Kadans panosunda yalnızca-zamanı-gelenler süzgeci (#/modes/followup). Yeni bir onay kutusu panoyu şu anda aksiyon alınabilir olanlarla sınırlıyor. Zamanın gelip gelmediği, üst projenin followup-cadence.mjs dosyasının zaten hesapladığı urgency alanından okunuyor (urgent / overdue) — asla izleyicinin status alanından değil; o alan applied/responded/interview değerlerini taşır ve hiçbir şeyle eşleşmezdi. Zamanı gelen bir şey yoksa pano, boş bir ekran göstermek yerine en yakın planlanmış takibi bildiriyor. Mantık, üst projedeki followup-view.mjs dosyasının aynası olan saf public/js/lib/followup-view.js modülünde yaşıyor.
  • Gizli işverenler, kendilerini sunan ajansa atfediliyor. İşvereni saklanan bir ilan izleyicide ? olarak kaydedilir ve işe alım uzmanı Via sütununa yazılır. #/tracker çıplak bir ? gösteriyordu; bu yüzden birden çok gizli satır birbirinden ayırt edilemiyor, logo çözücü de eşleştirecek bir şey bulamıyordu. Böyle bir satır artık “Gizli · <ajans> aracılığıyla” biçiminde okunuyor, logosunu ajans adından çözüyor ve arama kutusunda o adla bulunabiliyor. Yalnızca sunum — kanonik company alanının üzerine asla işe alım uzmanı yazılmıyor. Üst projedeki company-presentation.mjs dosyasının aynası olan yeni saf public/js/lib/company-presentation.js modülü.

Düzeltildi

  • Jobstreet/SEEK kullanımdan kaldırılmış bir uç noktayı çağırıyordu. Kaynak hâlâ SEEK’in emekliye ayırdığı chalice-search v4’e (/api/chalice-search/v4/search) işaret ediyordu; üst proje /api/jobsearch/v5/search adresine geçmiş, web-ui ise hiç takip etmemişti. Artık her Jobstreet/SEEK girdisi v5’i sorguluyor. v5 öğe biçimi doğal olarak okunuyor (iş URL’si id üzerinden kuruluyor, locations[0].label, advertiser.description, salaryLabel), v4’e özgü solrFields izdüşüm parametresi kalktı ve portals.yml dosyasında hâlâ ölü v4 yolunu sabitleyen bir girdi, pazar ana makine adını korurken yolu v5 üzerinde yeniden kuruluyor — kullanıcının düzenleme yapmasına gerek yok.

Notlar

  • career-ops 1.30.0 eşitliği (üst projenin HEAD’i 8d64f65 → 6cc46a4; VERSION dosyası hâlâ 1.30.0 diyor — release-please main’in gerisinde). Aktarılmayanlar ve gerekçeleri: iCIMS JSON-LD konum doldurma — web-ui’nin iCIMS kaynağında hiç enrichDate() kancası yok (yalnızca liste sayfaları), dolayısıyla düzeltilecek bir kod yolu da yok; ölümcül olmayan CLI stderr (#1974) — web-ui’nin çalıştırıcısı başarısızlığa yalnızca çıkış koduna bakarak karar verir ve o buluşsal yönteme hiç sahip olmadı; Turbopack yol izleme — web-ui’de paketleyici yok; cv-sync-check düzeltmeleri — salt okunur ve fail-soft biçimde aktarılıyor; scan.mjs içinde Playwright sıralaması, Block H yanıtları, updater/doctor/update-system korumaları, özyinelemeli sözdizimi denetimi, Go panosu ve jd-skill-gap/verify-cv-facts öz-testlerine yapılan eklemeler — web-ui’nin çağırmadığı yalnızca-CLI yüzeyleri veya davranış değiştirmeyen öz-testler. Test paketi: 2818 → 2837.

[1.226.0] — 2026-08-27

Eklendi — iki Vietnam iş kaynağı: ITviec ve CareerViet.

Eklendi

  • ITviec + CareerViet (Vietnam). Host-sabitlemeli iki Vietnam panosu provider: itviec / provider: careerviet girdileriyle tarayıcıya katılır: ITviec (itviec.com, teknoloji) ve CareerViet (careerviet.vn, geniş kapsam). İkisi de token gerektirmeyen HTML kazıyıcılardır; SSRF host-pin, yalnızca-HTTPS, şirket bazında fail-soft ve sayfa üst sınırları içerir. Kayıt artık 85 kaynak (80 EN + 5 RU), ALL_ADAPTERS 80 taşır — ikisi de #/scan Kaynak filtresinde görünür.

Notlar

  • career-ops 1.30.0 paritesi (parentVersion 1.29.0 → 1.30.0). Taşınmadı (yalnızca CLI/topluluk veya zaten kapsanmış): Hired Wall, /calibrate, clean-markers, şablon paketleri, doctor, pdf/LaTeX ve web-ui’nin çağırmadığı eval/tracker/scan CLI’leri; _html-to-text düzeltmesi ve roleFuzzyMatch zaten vardı; title-filter stem: öneki ertelendi. Test paketi: 2818.

[1.225.1] — 2026-08-27

Düzeltildi — sağlayıcı logo afişi artık README ve yardımda görünüyor.

Düzeltildi

  • v1.225.0 afişi GitHub’da görünmüyordu: bağımsız images/providers.svg dosyasında GitHub’ın reddettiği geçersiz bir font-family (iç içe çift tırnak) vardı, <img> depo-göreli bir src kullanıyordu (ham HTML <img> GitHub’da göreli yolları çözmez) ve <p> bloğunda sondaki boş satır yoktu. Artık mutlak bir URL üzerinden işlenmiş bir images/providers.png gösteriyor, boş satırlarla ayrılmış olarak; SVG de geçerli XML’e düzeltildi.

Notlar

  • Yalnızca dokümanlar; kod veya test değişikliği yok. cvstart.org vitrini ve uygulamanın kutucukları zaten doğruydu (satır içi SVG, bu dosya değil). 2784

[1.225.0] — 2026-08-27

Eklendi — README ve yardım kılavuzunda bir sağlayıcı logo afişi.

Eklendi

  • Sağlayıcı logo afişi. Tek ve kendi kendine yeten bir images/providers.svg — 18 LLM sağlayıcısı, simge yayımlayan 11’i için gerçek marka logosu (simple-icons, CC0) ve kalan 7’si için marka renkli monogram ile — artık README’nin (×17) ve uygulama içi yardım kılavuzunun başında. (Uygulama gerçek logo kutucuklarını kendisi çizer; afiş GitHub’da işlenir ve uygulamada XSS-güvenli işleyici tarafından kaldırılır.)

Notlar

  • Yalnızca dokümanlar — kod veya test değişikliği yok; SVG satır içidir (uzak kaynak yok). Tarama kaynakları değişmedi: 83. Test paketi: 2784.

[1.224.0] — 2026-08-26

Değiştirildi — LLM sağlayıcı kutucukları artık gerçek marka logolarını gösteriyor.

Değiştirildi

  • Gerçek sağlayıcı logoları. Sağlayıcı kutucukları — Ayarlardaki API anahtarı alanları, Kullanım satırları, pano çipi, Ayarların “Etkin” özeti, ⚡ değerlendirme sonucu ve karşılama afişi — artık açık kaynak simge yayımlayan 11 sağlayıcı için gerçek marka logosunu işliyor (Anthropic · Gemini · OpenAI · Qwen · OpenRouter · GitHub · DeepSeek · Kimi · MiniMax · Mistral · Ollama; simple-icons’ten tek yollu SVG’ler, CC0). Yayımlanmış simgesi olmayan 7’si (Hermes · GLM/Z.ai · Grok · Together · Fireworks · BytePlus Ark · Volcengine Ark) marka renkli monogramı korur. Hâlâ yapısı gereği CSP-güvenli: logo yolu gömülü statik bir sabit — uzak kaynak yok, innerHTML yok.

Notlar

  • Rota veya davranış değişikliği yok; aynı ProviderLogo.el(slug) API’si. provider-logo.js büyüdü (gömülü logo yolları). Tarama kaynakları değişmedi: 83. Test paketi: 2784.

[1.223.0] — 2026-08-26

Düzeltildi — başarılı bir ⚡ canlı değerlendirme hata olarak boyanıyordu; ayrıca OpenWorker coworker’ını doğrudan GitHub URL’sinden veya .zip’ten kurun.

Düzeltildi

  • ⚡ değerlendirme sonuç rozetinin tonu. Başarılı bir canlı değerlendirme artık başarısızlık gibi boyanmıyor. Süreç içi sağlayıcılar (OpenRouter, DeepSeek, …) alt süreç çıkış code’u döndürmez, bu yüzden katı code === 0 yanlıştı ve her başarı kırmızı görünüyordu (“exit 0” yazarken). Ton artık sonucu izliyor — yalnızca sıfırdan farklı kodla çıkan bir alt süreç kırmızı boyar; kodsuz bir canlı sonuç badge-ok’tur ve “· exit N” son eki yalnızca gerçek bir çıkış kodu varken görünür.

Değiştirildi

  • OpenWorker coworker’ını GitHub URL / .zip’ten kurun. Coworker’ın dokümantasyonu artık tek komutluk kurucuyu (curl … | bash, idempotent — mevcut career-ops / web-ui’yi yeniden kullanır) ve OpenWorker’daki üç kurulum yolunu (GitHub URL · .zip · tek dosya içe aktarma) docs/integrations/openworker.md, uygulama içi yardım §32 (×17) ve README’de açıklar.

Notlar

  • Uzun süredir açık olan bir kapsam boşluğu kapatıldı: Recruitee kaynağının artık v1.214.2 tırnaklı-açı düzeltmesi için uçtan uca bir testi var (bir etiket özniteliğindeki > açıklamaya sızmamalı). Tarama kaynakları değişmedi: 83. Test paketi: 2783.

[1.222.0] — 2026-08-26

Değiştirildi — genişletilmiş sağlayıcıların (DeepSeek … Volcengine Ark) alan ipuçları artık 17 dilin tamamında yerelleştirildi.

Değiştirildi

  • Sağlayıcı alan ipuçları yerelleştirildi. v1.216.0–v1.217.0’te eklenen 11 OpenAI uyumlu sağlayıcının (DeepSeek · GLM/Z.ai · Kimi · MiniMax · Mistral · Grok · Together · Fireworks · Ollama · BytePlus Ark · Volcengine Ark) her config.<slug>Hint değeri — Ayarlar → API anahtarları altındaki API anahtarı, model ve temel URL ipuçları — artık İngilizceye geri düşmek yerine 17 dilin tamamına çevrildi. Kayıt URL’leri, model id’leri ve ⚡ canlı değerlendirme işareti aynen korunur.

Notlar

  • Davranış değişikliği yok — field-specs.js içindeki İngilizce hintFallback eksik bir anahtarı hâlâ korur ve yeni bir sözleşme testi, alan tanımlayıcılarının her hintKey değerinin 17 dilde çözümlendiğini doğrular. Tarama kaynakları değişmedi: 83. Test paketi: 2779.

[1.221.0] — 2026-08-26

Güvenlik — tarayıcı fetch yolunda DNS-rebinding’e karşı derinlemesine savunma.

Güvenlik

  • Tarayıcının HTTP çekirdeği (server/lib/http-json.mjs içindeki fetchJson/fetchText) artık her kaynağın ana bilgisayarını gerçek ağ yolunda çözüyor ve özel, loopback, link-local, CGNAT veya bulut meta veri adresine çözülürse bağlanmayı reddediyor — bir DNS-rebinding vektörünü kapatıyor. Tarayıcı ana bilgisayarları zaten genel alan adlarına sabitlenmiş, dolayısıyla bu derinlemesine savunmadır; kullanıcı URL yolunda zaten daha güçlü bağlantı sabitleme (safe-fetch.mjs) vardı. Koruma yalnızca gerçek fetch taşımasında çalışır — enjekte edilen test fetchImpl’i asla çözülmez.

Notlar

  • Sağlıklı bir taramada davranış değişmez. Tarama kaynakları değişmedi: 83. Testler: 2775.

[1.220.0] — 2026-08-26

Eklendi — tek girişten birden çok Get on Board kategorisi tarayın.

Eklendi

  • Bir getonbrd girişi artık yalnızca programming akışı yerine categories: [programming, operations-management, machine-learning-ai] (ya da tek bir category:) ayarlayabilir; ilanlar kategoriler arasında URL’ye göre yinelenenlerden arındırılır, en fazla 12. Mevcut girişler aynı kalır (varsayılan hâlâ programming).

Notlar

  • Yalnızca sunucu; SSRF ana bilgisayar sabitlemesi (www.getonbrd.com) ve redirect:'error' değişmez, geçersiz bir kategori slug’ı herhangi bir istekten önce reddedilir. Tarama kaynakları değişmedi: 83. Testler: 2771.

[1.219.0] — 2026-08-26

Eklendi — Torre tarayıcıya katıldı ve artık her sağlayıcı etiketi doğru.

Eklendi

  • Torre (provider: torre) — torre.ai’nin pan-Latin Amerika yetenek pazarı; Greenhouse/Lever/Ashby’ye ulaşmayan uzaktan roller taşıyan, kimlik doğrulaması gerektirmeyen açık bir arama; giriş başına tek sınırlı istek. Kayıt artık 83 kaynak içeriyor (78 İngilizce + 5 Rusça). Ayrıca karşılama afişinde aktif sağlayıcının monogramı.

Düzeltildi

  • a16z Speedrun taraması, dönen bir panoda erken duruyordu (tarama ortasındaki kısa bir sayfa sonuncusu sanılıp ~300’de 149’a kırpılıyordu); artık akışın kendi total_pages değerine güveniyor. Karşılama afişi ise sağlayıcıyı 4 girişli bir haritadan çözüyordu (kalan 14 için ham slug gösteriyordu) — şimdi 18’in etiket+monogramını kullanıyor; Ayarlar’daki sağlayıcı notu 7’den 18’e çıkıyor.

Notlar

  • Get on Board’un giriş başına çoklu kategori seçeneği burada henüz bağlı değil (kaynak düzeyinde bir refactor gerekiyor). Testler: 2768.

[1.218.0] — 2026-08-26

Eklendi — sağlayıcının gösterildiği her yerde sağlayıcı rozetleri (ve doğru adlar).

Eklendi

  • Pano çipinde, Ayarlar’daki “Etkin” özetinde ve ⚡ değerlendirme sonucu başlığında sağlayıcı monogramları.

Düzeltildi

  • Eski etiketler: üç ekran adı 5 girişli bir haritadan çözüyordu (değerlendirme sonucu Anthropic olmayan her sağlayıcıyı “Gemini” olarak yanlış etiketliyordu); artık paylaşılan ProviderStatus.label (18) kullanıyor. Anahtar sayısı “/ 7” gösteriyordu → 18. LLM_PROVIDER ipucunun slug listesi 17 dilin tümünde ark / arkcn kazandı.

Notlar

  • Yalnızca istemci, CSP güvenli. Sunucu değişikliği yok. Tarama kaynakları: 82. Testler: 2758.

[1.217.1] — 2026-08-26

Test sağlamlaştırma — tüm sağlayıcı listesi için uç nokta kapsamı.

Eklendi

  • Kimi, MiniMax, Mistral ve Fireworks için uç noktayı, varsayılan modeli ve Bearer kimlik doğrulamasını doğrulayan parametreli bir run<Provider> testi.

[1.217.0] — 2026-08-26

Eklendi — Ark, LLM listesine katılıyor (18 sağlayıcı). ByteDance’in Doubao modelleri BytePlus Ark ve Volcengine Ark artık ⚡ canlı sağlayıcılar — aynı OpenAI uyumlu çekirdek ve bölgeye göre temel URL ile.

Eklendi

  • BytePlus Ark (ARK_API_KEY, uluslararası) ve Volcengine Ark (ARK_CN_API_KEY, Çin) — runOpenAICompatible() üzerinden OpenAI uyumlu Chat Completions. ARK_MODEL / ARK_CN_MODEL (bir Doubao model adı ya da ep-… uç nokta id’niz) ayarlayın; ARK_BASE_URL / ARK_CN_BASE_URL bölgeyi değiştirir. İkisi de auto sırasına (en sona) katılır; Ayarlar ve Kullanım’da monogramlarıyla görünür. Web arayüzü artık 18 sağlayıcıyı canlı kapsıyor.

Notlar

  • Geri kalanla aynı güvenilir yapılandırma + http(s) şema denetimi yolu (asla iş ilanı URL’si için SSRF doğrulayıcısı değil). Tarama kaynakları değişmedi: 82. Testler: 2755.

[1.216.0] — 2026-08-26

Eklendi — dokuz LLM sağlayıcısı daha, her birinin kendi marka karosu. ⚡ Canlı değerlendirmelerin artık DeepSeek, GLM (Z.ai), Kimi (Moonshot), MiniMax, Mistral, Grok (xAI), Together, Fireworks veya tamamen yerel Ollama üzerinden çalışabilir — bir anahtar kadar uzakta, her biri Ayarlar’daki alanının yanında bir monogramla işaretli.

Eklendi

  • Dokuz OpenAI uyumlu sağlayıcı. DeepSeek, GLM (Z.ai), Kimi (Moonshot), MiniMax, Mistral, Grok (xAI), Together AI, Fireworks AI ve Ollama (tamamen yerel, anahtarsız). Ayarlar’da bir anahtar — Ollama için OLLAMA_BASE_URL — girin; Hermes’ten sonra auto sırasına katılır; herhangi birini LLM_PROVIDER ile sabitleyin. Together, Thinking Machines’in Inkling modelini de (thinkingmachines/Inkling) barındırır. Web arayüzü artık 16 sağlayıcıyı canlı kapsıyor.
  • Sağlayıcı monogramları. CSP güvenli, marka renginde bir baş harf karosu her sağlayıcıyı Ayarlar’daki anahtar alanının yanında ve Kullanım sayfasındaki satırında işaretler — satır içi SVG, harici logo yok, hiçbir şey cihazından çıkmaz.

Notlar

  • Sağlayıcıların temel URL’leri, runOpenAICompatible() üzerinden http(s) şema denetimiyle (Ollama’nın loopback’ine izin verilir) geçen güvenilir yapılandırmadır; asla iş ilanı URL’si için SSRF doğrulayıcısından geçmez. Tarama kaynakları değişmedi: 82. Testler: 2752.

[1.215.0] — 2026-08-26

Eklendi — tüm iş aramanı OpenWorker’dan yürüt. Yeni bir coworker bu hattı Andrew Ng’nin açık kaynak yapay zekâ coworker uygulamasından yürütür ve uygulama içi yardım artık bunu kapsar, böylece Belgelere Sor asistanı sana yol gösterebilir.

Eklendi

  • OpenWorker coworker. Kodsuz bir OpenWorker coworker’ı — Fighter90/career-ops-coworker — tüm iş aramayı (tara, puanla, uyarla, izle, takip et) yürütür ve bu panoyu başlatabilir, hepsi masaüstünde. 17 dilde sunulan tek dosyalık bir persona olup OpenWorker’ın kendi yükleyicisiyle kurulabilir olduğu doğrulanmıştır.
  • Yardım §32 “Run it from OpenWorker” (17 dilin tümü) bunu belgeler; böylece uygulama içi Belgelere Sor asistanı ve yüzen yardım düğmesi hakkında soruları yanıtlayabilir. Ayrıca açılış sayfası altbilgisinden, README’den, wiki’den ve docs/integrations/openworker.md’den bağlanmıştır.

Notlar

  • Yalnızca belgeler + site — uygulama kodu değişikliği yok. Tarama kaynakları 82’de değişmedi. Test takımı: 2742.

[1.214.2] — 2026-08-25

Düzeltildi — paylaşılan HTML→metin hattı (Greenhouse / Recruitee açıklamaları) bir öznitelik değeri > karakteri içerdiğinde artık etiket özniteliklerini açıklamaya sızdırmıyor.

Düzeltildi

  • Öznitelik içinde > bulunan HTML açıklamaları temiz biçimde ayıklanıyor. Greenhouse ve Recruitee açıklamalarının arkasındaki etiket ayıklayıcı ilk >’de duran naif bir eşleşme kullanıyordu, bu yüzden <a title="salary > 100k"> gibi bir etiket sondaki öznitelik metnini (100k">) açıklamada bırakıyordu. Artık tırnaklı öznitelik değerlerine (tek veya çift) saygı gösteriyor, varlıkları çözmeden önce işaretlemeyi ayıklıyor (bir öznitelik içindeki kodlanmış tırnak sahte bir sınırlayıcı olmasın diye) ve düz metinde sabit bir <>’i hâlâ koruyor.

Notlar

  • Test takımı: 2742. Tarama kaynakları 82’de değişmedi. Bu turda üst projeden başka yeni bir şey yok: kalan değişiklikler salt-okunur olarak aktarılıyor (follow-up / weekly-digest / rejection-latency / salary-gap düzeltmeleri web-ui değişikliği gerektirmiyor) ya da web-ui yüzeyi değil (harici bir X/Xquik BYO-key eklentisi, CLI/verify düzeltmeleri). İsteğe bağlı öğeler — SmartRecruiters ayrıntı açıklamaları, detect-reposts toplayıcı atlaması, stem: / word: başlık önekleri, DNS-rebinding sıkılaştırması — sırada bekliyor.

[1.214.1] — 2026-08-25

Düzeltildi — Ashby iş açıklamaları artık Greenhouse ve Recruitee ile aynı uzunlukta kırpılıyor, böylece bir içerik filtresi üç panoda da aynı davranıyor ve tek bir pano tarama önbelleğini şişiremiyor.

Düzeltildi

  • Ashby açıklamaları artık diğer panolarla aynı uzunluk sınırına uyuyor. v1.214.0 Ashby’nin ilan gövdesini içerik filtresine veriyordu, ama — 4000 karakterde kırpan Greenhouse ve Recruitee’nin aksine — Ashby’ninki sınırsız doğrudan eşleniyordu (bazıları 4 kat uzun). Böylece aynı content_filter kelimesi, yalnızca metinde nereye düştüğüne göre Ashby’de eşleşip Greenhouse’da eşleşmeyebiliyordu ve tek bir pano, #/scan’in yüklediği tarama önbelleğine yüzlerce KB ekleyebiliyordu. Ashby artık aynı 4000 karaktere kırpılıyor (metni zaten düz olduğundan kesiliyor, asla etiketten arındırılmıyor).

Notlar

  • Test takımı: 2738. Tarama kaynakları 82’de değişmedi.

[1.214.0] — 2026-08-25

Düzeltildi — Greenhouse, Ashby ve Recruitee iş açıklamaları artık içerik filtresini besliyor, böylece kelime / ülke / vize filtreleri bu panolarla gerçekten eşleşiyor; ve “Associate <kıdemli unvan>” (akademik rütbeler dâhil) artık başlangıç seviyesi olarak yanlış sınıflandırılmıyor.

Düzeltildi

  • İçerik filtreleri artık Greenhouse, Ashby ve Recruitee’de çalışıyor. Bu panolar artık her ilanın tam metnini açıklaması olarak taşıyor, böylece açıklamayı okuyan bir content_filter (ya da ülke / vize kelime filtresi) panoyu körlemesine geçirmek yerine ilan gövdesiyle eşleşiyor. Ashby ve Recruitee gövdeyi liste yükünde bedavaya veriyor; Greenhouse zaten veriyordu. Üçü de tek bir paylaşılan HTML→metin hattından geçiriliyor.
  • “Associate Director” / “Associate Professor” başlangıç değil, kıdemlidir. Kıdem sınıflandırıcısı (skip_tiers: tarafından kullanılır) “associate” kelimesini kıdemli bir unvanı önlese bile başlangıç seviyesi işareti sayıyordu. Artık “Associate <kıdemli isim>”—akademik rütbeler dâhil (Associate Professor, Associate Dean)—kıdemli okuyor, gerçek başlangıç varyantlarını (Associate Attorney, Associate Editor) başlangıç seviyesinde tutuyor ve baştaki “Intern, Associate Dean”i hâlâ staj olarak sınıflandırıyor.

Notlar

  • Test takımı: 2736. Tarama kaynakları 82’de değişmedi. Sonraya sıraya alındı: isteğe bağlı SmartRecruiters açıklama zenginleştirmesi (ilan başına bir detay isteği), detect-reposts’un aggregator: true pano atlaması ve sabitlenmiş kelime stem: / word: başlık önekleri — her biri varsayılan davranış değişikliği değil, isteğe bağlı bir yapılandırma. DNS-rebinding sıkılaştırması kendi güvenlik sürümü için hâlâ sırada.

[1.213.0] — 2026-08-22

Eklendi — Singapur’un ulusal iş bankası MyCareersFuture bir tarama kaynağı olarak. Düzeltildi — Greenhouse ilanları artık içerik filtrelerinin çalışması için tam metnini taşıyor ve uzaktan Ashby rolleri yalnızca-şehir bir konumun arkasında gizlenmiyor.

Eklendi

  • MyCareersFuture (Singapur) (mycareersfuture.gov.sg) — Workforce Singapore tarafından işletilen Singapur ulusal kamu iş bankası için yeni, token gerektirmeyen bir tarama kaynağı. #/scan sayfasındaki Kaynak filtresinden seçin ya da isteğe bağlı bir keywords listesiyle provider: mycareersfuture olan bir şirket ekleyin (yoksa Job Bank gibi profilinizin hedef rollerine düşer). Genel arama API’sini okur, ana bilgisayara sabitli, anahtarsız.

Düzeltildi

  • Greenhouse ilanları artık içeriğe göre filtrelenebiliyor. Greenhouse panoları ilanın tam gövdesiyle çekilir, ilanın açıklaması olarak düz metne çözülür — böylece açıklamayı okuyan bir content_filter (ya da ülke/vize kelime filtresi) artık Greenhouse ilanlarını körlemesine geçirmek yerine gerçekten eşleştirir.
  • Uzaktan Ashby rolleri artık bir şehir filtresiyle elenmiyor. Ashby çalışma modelini (Remote/Hybrid/Onsite) ofis şehrinden ayrı tutar, bu yüzden tamamen uzaktan bir rol hâlâ örn. “San Francisco” olarak okunuyordu — ve o şehri engelleyen bir konum filtresi kabul edebileceğiniz bir rolü gizliyordu. Rol uzaktansa artık konuma “Remote” eklenir ve ofise bağlı bir hibrit rolün yanlış etiketlenmemesi için workplaceType, eskimiş bir isRemote bayrağına üstün gelir.

Notlar

  • Tarama kaynakları: 82 (77 İngilizce + 5 Rusça). Test takımı: 2724. Bir DNS-rebinding sıkılaştırması (bir ana bilgisayarın çözümlenen adresini bağlanmadan önce doğrulamak) özel bir sürüm için sıraya alındı — doğrudan bir port yerine web-ui’ye özgü bir tasarım gerektiriyor.

[1.212.1] — 2026-08-21

Düzeltildi — cvstart.org açılış sayfası tarayıcının iş kaynaklarını eksik sayıyordu (80 gösteriyor ve Job Bank (Kanada)’yı atlıyordu); artık uygulamanın 81’iyle yeniden eşleşiyor ve ikisi ayrışırsa site derlemesi yüksek sesle başarısız oluyor.

Düzeltildi

  • Açılış sayfasının “İş kaynakları” sayımı uygulamayla yeniden senkron. v1.212.0 sonrasında cvstart.org 80 pano gösteriyor ve yeni Job Bank (Kanada) çipi eksikti; oysa uygulama, tarama açılır menüsü ve yardım kılavuzu hepsi 81 listeliyordu. Açılış sayfası listesini canlı tarayıcı kaydını yükleyerek kurar ve bir kaynak, bir YAML bağımlılığını içeri alma biçimi yüzünden o derlemede yüklenemedi — böylece sessizce düştü. Job Bank artık bu bağımlılığı, uygulamanın geri kalanının tarama sırasında yaptığı gibi tembel yükler, dolayısıyla her zaman görünür.
  • Site derlemesi artık uyuşmayan bir kaynak sayısını yayımlamayı reddediyor. Kayıt, diskte var olandan daha az kaynak sayarsa (yüklenemeyen bir kaynağın izi), derleme yanlış sayıyı sessizce yayımlamak yerine açık bir mesajla başarısız olur.

Notlar

  • Uygulama davranışı değişmedi — tarayıcıda her zaman 81 kaynağın tümü vardı; yalnızca açılış sayfası etkilendi. Tarama kaynakları: 81 (76 İngilizce + 5 Rusça) — değişmedi. Test takımı: 2687.

[1.212.0] — 2026-08-21

Eklendi — Job Bank (Kanada), federal ulusal iş panosu. Kaldırıldı — EchoJobs (beslemesi artık bot korumasının arkasında). Düzeltildi — Consider tabanlı panolar yeniden sonuç döndürüyor ve çok konumlu Lever ilanları artık konumlarının yarısını gizlemiyor.

Eklendi

  • Job Bank (Kanada) (jobbank.gc.ca) — hiçbir toplayıcının iyi kapsamadığı yüksek hacimli bir pano olan Kanada federal ulusal istihdam hizmeti için yeni, token gerektirmeyen bir tarama kaynağı. #/scan sayfasındaki Kaynak filtresinden seçin ya da isteğe bağlı bir keywords listesiyle provider: jobbankca olan bir şirket ekleyin (yoksa profilinizin hedef rollerine düşer). Genel ATOM beslemesini okur, ana bilgisayara sabitli, anahtarsız.

Kaldırıldı

  • EchoJobs — emekliye ayrıldı. Genel beslemesi artık bot korumasının arkasında ve hiçbir şey döndürmüyor; onu tutmak yalnızca bir tarama yuvası harcıyordu.

Düzeltildi

  • Consider tabanlı panolar yeniden sonuç döndürüyor. Consider artık aramayı kabul etmeden önce anonim bir el sıkışma (oturum çerezi + CSRF belirteci eken bir GET) istiyor; onsuz istek sessizce reddediliyor ve pano boş görünüyordu.
  • Çok konumlu Lever ilanları artık konumlarının yarısını gizlemiyor. Lever bir birincil şehri location’a, geri kalanını allLocations’a koyar; yalnızca birincili okumak, Barselona VE Montevideo’da açık bir ilanı yalnızca-Barselona gibi gösteriyordu (ve bir konum filtresince yanlışlıkla eleniyordu). Artık ikisi birleştiriliyor.

Notlar

  • Sayfalanmış panolarda sayfalar arası tempo daha yumuşak (150 yerine 250 ms), tek ana bilgisayarlı kariyer sitelerine nezaketen. Tarama kaynakları: 81 (76 İngilizce + 5 Rusça) — değişmedi (Job Bank girdi, EchoJobs çıktı). Test takımı: 2685.

[1.211.0] — 2026-08-19

Eklendi — Yourator, Tayvanlı bir teknoloji iş panosu. Düzeltildi — başlık/şirket adındaki aksanlı varlıklar artık her yerde çözülüyor ve adında aksan olan bir şirket artık yanlışlıkla işaretlenmiyor.

Eklendi

  • Yourator (yourator.co) — Tayvan teknoloji ve dijital iş pazarı için yeni, token gerektirmeyen bir tarama kaynağı. #/scan sayfasındaki Kaynak filtresinden seçin ya da provider: yourator olan bir şirket ekleyin. Genel JSON API’sini okur (anahtar yok, tarayıcı yok), panonun her sayfasını gezer ve her ilanın gerçek işveren bağlantısını (kendi ATS’i) izleme parametreleri temizlenmiş olarak verir.

Düzeltildi

  • Aksanlı adlandırılmış varlıklar artık her yerde çözülüyor. Paylaşılan HTML çözücü Latin-1 harflerini kazandı (&eacute; → é, &ccedil; → ç, …); böylece D&eacute;veloppeur ya da Fran&ccedil;ais yazan bir Avrupa panosu bu düz metni artık bir başlıkta, izleyicide veya üretilen bir belgede bırakmıyor. (Büyük harfler büyük kalır — &Eacute; É’dir, é değil — ve &constructor; gibi bir arama artık kendisine çözülür.)
  • Adında aksan olan bir şirket, kendi alan adında olduğu için artık yanlışlıkla işaretlenmiyor. “Işık” artık “isik” olarak katlanıp isik.com.tr ile eşleşiyor; “Société Générale” societegenerale.com ile eşleşiyor. Eski denetim aksanlı harfleri ASCII tabanına katlamak yerine siliyordu.

Notlar

  • Tarama kaynakları: 81 (76 İngilizce + 5 Rusça). Test takımı: 2667.

[1.210.1] — 2026-08-19

Düzeltildi — “&” ya da tırnak içeren Habr Career ilan başlıkları ve şirket adları artık bozuk gelmiyor.

Düzeltildi

  • Habr Career kaynağı artık başlık ve şirket adı içindeki HTML varlıklarını ileri akmadan önce çözüyor. Sunucuda işlenen kartlar kaçışlı geliyor (“Changellenge >>”, “Demand Forecasting & Inventory Optimization”, “ООО "М-ТЕХ"”); bu yüzden çözülmemiş bir “&”, kendi “&” başlık filtrenizde sessizce başarısız oluyordu — önceki sürümün diğer beş panoda kapattığı belirtinin aynısı — ve şirket adları izleyiciye ve raporlara bozuk ulaşıyordu. Varlık çözme artık etkilenen altı kaynağın tamamında tamamlandı.

Notlar

  • Test takımı: 2644.

[1.210.0] — 2026-08-19

Eklendi — Senjob, tarayıcının ilk Afrika iş ilan panosu (Senegal); beş panoda daha isabetli başlık eşleştirme.

Eklendi

  • Senjob (senjob.com) — Senegal için yeni, token gerektirmeyen bir tarama kaynağı ve tarayıcının ilk Afrika panosu. #/scan sayfasındaki Kaynak filtresinden seçin ya da provider: senjob olan bir şirket ekleyin. Genel listeyi düz HTTP ile okur (anahtar yok, tarayıcı yok), her isteği senjob.com’a sabitler ve — HTML ayrıştırdığı için — birden hiçbir şey döndürmeyen bir listeyi işsiz bir ülke değil, bozuk bir pano (görünür bir hata) olarak ele alır.

Düzeltildi

  • İçinde “&” olan başlıklar artık beş panoda ilan düşürmüyor — beesite, Cornerstone (csod), Hacker News “Who is hiring”, Phenom ve TKMS’te başlıklar HTML kaçışlı gelir; bu yüzden “R&D Engineer” gibi bir roldeki kaçışlı “&”, kendi “r&d” anahtar kelimenizde başarısız olur ve ilan sessizce kaybolurdu (“sales & marketing” vetosu da hiç tetiklenmezdi). Artık başlıklar — ve Phenom konumları — filtrelemeden önce çözülür.

Notlar

  • Tarama kaynakları: 80 (75 İngilizce + 5 Rusça). Test takımı: 2643.

[1.209.0] — 2026-08-17

Eklendi — uygulama içi yardım artık bir başvurunun sonucunu kaydetmeyi kapsıyor ve “Dokümana sor” seni oraya yönlendirebiliyor.

Eklendi

  • İzleyici yardımı (§11) 17 dilin tümünde bir “Bir sonucu kaydet” bölümü kazandı; Sonuç düğmesini anlatıyor: ne olduğunu seç (reddedildi / teklif / işe alındı / geri çevrildi / görmezden gelindi / mülakata geçti), ne yapacağını önizle, sonra kaydet — bu, sonucu not eder, gönderdiğin CV ve ön yazıyı arşivler ve satırın Durumunu senin yerine eşitler. Yüzen “Dokümana sor” yardımcısı bu kılavuzu okur, bu yüzden artık yalnızca Durumu elle düzenlemeni önermek yerine seni o düğmeye yönlendirir.

Notlar

  • Her yardım paketi artık 31 H2 / 119 H3 (önceden 118); eşlik bekçileri buna göre yükseltildi. Yalnızca belge — kod veya davranış değişikliği yok. Takım: 2625.

[1.208.2] — 2026-08-16

Düzeltildi — telefonda bildirim ve tema düğmeleri artık arama kutusunun üstünde durmuyor.

Düzeltildi

  • v1.208.1, üst çubuğun düğmelerinin sayfa başlığıyla çakışmasını önledi ama dar — en dar olmasa da — bir telefonda, özellikle düğme etiketleri uzun olan dillerde, çubuğun tamamı yine tek satıra sıkışıyor, böylece 🔔 ve 🌙 düğmeleri arama kutusunun üstüne binebiliyordu. İşlem düğmeleri (bildirimler, tema, Tanılama, Scan Aç) artık telefonda her zaman tam genişlikte kendi ikinci satırına iniyor; böylece arama kutusu tümüyle okunabilir kalıyor ve hiçbir şey çakışmıyor.

Notlar

  • Telefonda çubuğun işlem düğmeleri tam genişlikte ikinci bir satıra taşınarak, düzenin artan negatif alanı çakışma olarak dağıttığı kırılgan “neredeyse dolu satır” bandını ortadan kaldırıyor. Bir Playwright bekçisi artık tam tetikleyiciyi — 565–640px bandında uzun etiketli bir dil — yeniden üretiyor ve çubuğun denetimlerinin asla piksel paylaşmadığını doğruluyor. Takım: 2621.

[1.208.1] — 2026-08-16

Düzeltildi — telefonda üst çubuğun düğmeleri artık sayfayla çakışmıyor.

Düzeltildi

  • v1.208.0, dar ekranlarda üst çubuğun işlem düğmelerini (Tanılama, Scan Aç, bildirimler, tema) ikinci satıra kaydırıyordu ama çubuk sabit yükseklikte kaldığından, kaydırılan satır taşıp sayfa başlığının üstüne biniyordu. Çubuk artık satırlarını almak için büyüyor ve içerik altından akıyor.

Notlar

  • Çubuğun sabit height değeri min-height oldu; böylece her genişlikte içerikle birlikte büyüyor (masaüstü değişmedi). Bir Playwright bekçisi artık çubuğun sayfaya taşmadığını da denetliyor. Takım: 2621.

[1.208.0] — 2026-08-16

Düzeltildi — uygulama artık bir telefon ekranına sığıyor: yana kaydırma bitti.

Düzeltildi

  • Dar ekranda uygulamanın tamamı yana kayıyordu — üst çubuk, tablolar, yardım makaleleri ve ayar sekmeleri sağ kenarı aşıyordu. Artık her sayfa her genişliğe sığıyor: üst çubuk düğmeleri ikinci satıra kayar, geniş tablolar ve kod blokları kendi kutusunda kayar, yardım içindekiler tablosunu makalenin üstüne yığar, düğme/sekme satırları alt satıra geçer ve uzun yollar veya URL’ler sayfayı germek yerine satır kırar.

Notlar

  • Kök neden klasik flex/grid min-width: auto tuzağı ve birkaç sarmalanmamış geniş öğeydi; ızgara öğelerine min-width: 0, markdown/başlıklara overflow-wrap, kaydırılabilir bir markdown tablosu ve mobil kırılma noktasında yardım ızgarasının dikey yığılmasıyla düzeltildi. Bir Playwright bekçisi ana rotalarda 375 px’te 0 yatay taşma doğrular. tests/playwright-smoke.mjs. Takım: 2621.

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