Changelog

GitHub

Jede nennenswerte Änderung, Release für Release. Dieselbe Datei liegt im Repository und ist in alle 19 Sprachen übersetzt.

[1.267.1] — 2026-11-04

Behoben

  • Release-Zug-Reparatur (die CI-Gates von v1.267.0) — die Testzähler-Kette in PROJECT-CONTEXT bricht an der v1.267.0-Spitze nicht mehr (das Pfeil-Format, das der Eval-Grader matcht), die QA-Prompts werden neu organisiert (ein Live-Prompt pro Release, v1.266.0 archiviert), und die Coverage pro Datei wird über den 98/90-Ratchet gehoben: der applicantpro-Salary-Renderer verliert einen unerreichbaren Fallthrough (salaryRangeOf erweist sich als nur undefined, {min}, {max} oder {min,max} liefernd), wobei die einseitigen ≥/≤-Zweige jetzt durch den Fetch-Flow gepinnt sind, und die board-response-cache-Suite pinnt den no-store-Bypass, den vom Aufrufer gelieferten 304 gegen ein nicht gespeichertes Board und die MAX_ENTRIES-Verdrängung.
  • Tests: die Live-Zählung ist 7395 (die Suiten der v1.266.0/1.267.0-Welle tragen mehr Specs, als die früheren Notizen verfolgten — die Kette wird auf den gemessenen Boden neu verankert: 7392 nach der Welle, + 3 Gate-Tests in diesem Patch); Abdeckung 98.51 Zeile / 90.35 Zweig.

Hinweise

  • Der Tag v1.267.0 bleibt auf dem roten Merge-Commit — nicht umgezeigt (der Server lehnt umgezeigte Tags ab); v1.267.1 ist das Deploy-Fahrzeug.

  • Patch-Reparatur des Zugs v1.267.0: die CI-Gates sind grün, der Code-Baum hat sich im Wesentlichen nicht geändert.

[1.267.0] — 2026-11-04

Neu

  • Vier neue Scan-Quellen — GermanTechJobs, Darwinbox, Keka, ApplicantPro/isolved (Register 125 → 129 = 124 EN + 5 RU · 124 Adapter) — die zweite Parent-Sync-Welle gegen career-ops @ 7d8feb6d (87 Upstream-Commits). GermanTechJobs (#6346): board-weites RSS unter germantechjobs.de/rss (~626 Einträge in einer einzigen Anfrage); der Arbeitgeber ist das letzte " @ "-Segment des Titels — ein Titel ohne ein solches Segment wird verworfen, nie dem Board als Arbeitgeber zugeordnet; nur explizite provider:-Auswahl. Darwinbox (#6416): zero-auth alljobs-JSON hinter <tenant>.darwinbox.in, die Firmen-ID kommt aus der Careers-URL, paginierter POST-Walk (50/Seite, max_pages 20/200) mit dem Kurzseiten-Stopp aus der eigenen Zeilenzahl der Quelle. Keka (#6199): zwei Anfragen — eine Careers-Shell mit redirect:'manual', deren Skript die Feed-UUID nennt (ein unbekannter Tenant wird per 302 auf TenantNotFound.html weitergeleitet und liest sich als benannter 404), danach der gesamte offene Bestand in einem embed-jobs-Array. ApplicantPro / isolved (#6252): die numerische domainId aus dem Bootstrap, dann {success, data:{jobs, jobCount}}; jobCount > rows warnt, dass die Liste unvollständig ist; opt-in applicantpro: { fetchDetails: true } reichert über JSON-LD an, mit 250-ms-Pacing.
  • ETag-Wiederverwendung von Board-Antworten (#6105) — innerhalb eines Scans wird eine in den letzten 15 Minuten geladene Board-Antwort unverändert wiederverwendet, ältere revalidieren per If-None-Match (304 behält den Body); der Cache-Key deckt Methode + URL + Credential-Header + Body ab, sich überlappende Lesevorgänge kollabieren auf das laufende Promise, und CAREER_OPS_HTTP_CACHE=0 / _TTL_MS überschreiben das. Im Speicher, je Scan-Lauf (web-ui hat keinen On-Disk-Cache-Contract) — als Abweichung vermerkt.

Behoben

  • Publikationsdaten auf vier Boards (#6274) — remoteok, remotive, workingnomads und IBM geben jetzt ein Publikationsdatum aus, sodass der „Posted within“-Filter dort wirkt; der naive Zeitstempel von remotive wird UTC-normalisiert (der maschinenabhängige Alters-Bug war live), IBM _source fragt dcdate tatsächlich an.
  • Ein falsch geschriebener portals.yml-Key wird zurückgewiesen (#6107) — der EN-Scan wirft jetzt vor jedem Fetch einen benannten Fehler (Datei + Key + Vorschlag des nächstgelegenen Keys, Levenshtein ≤ 2), statt titel_filter: still zu ignorieren.
  • getro läuft über einen alten Featured-Pin hinaus weiter (#6406) — eine gepinnte veraltete Stellung wird weiterhin verworfen, beendet die Paginierung aber nicht mehr; der Walk endet auf einer echten kurzen Seite.

Hinweise

  • Bewusst nicht getan: der Seen-Filter des RU-Scanners ist nicht sprachbewusst, und sein Portals-Parse-Pfad läuft nicht durch das Misspelled-Key-Gate (Hand-offs in der Wellen-Spec festgehalten — noch kein RU-Board liefert Zeilen je Sprache); remoteok behält seinen offset-tragenden Datums-String, statt ihn zu UTC-normalisieren (seine Live-Form ist deterministisch). Tests 7096 → 7243; Playwright 173 pass / 0 fail / 1 opt-in skip; Register 129 = 124 EN + 5 RU · 124 Adapter (alle Zähl-Gates aus dem lebenden Register regeneriert).

[1.266.0] — 2026-11-01

Neu

  • Personio-Sprachversionen fressen einander nicht mehr auf (CAR-223: Parent #4789 + #5044 + #5285) — der vertagte Stack, als eigenes Release ausgeführt. Scan-Seite (#4789): scan_history.dedup_include_language: true (strikt opt-in — OFF ist byte-identisch) lässt Sprachversionen eines Postings die Dedup über die Seen-History-Varianten-Mechanik überleben (languageFormsFromUrl / recordUrlVariant / isUnseenLanguageVersion); der kanonische Key streift language/lang/locale-Parameter. preferred_languages (#5285): ordnet die Versions-Zeilen eines Postings preferred-first (stabil, bei Gleichstand Provider-Reihenfolge) — unabhängig vom Schalter (OFF behält die bevorzugte Version, ON behält jede Version in dieser Reihenfolge), mit einem validatePreferredLanguages-Port von validate-portals. personio-Fan-out (#5044): die Careers-Seite wird ohne den ?language=en-Zwang geladen (der eigene ?language=xx eines Tenants wird respektiert) und liefert eine Zeile je Sprachversion mit language + ?language=<code>-URLs; dedupIncludeLanguage ergänzt Fetches je Sprache (Deckel 5, gedrosselt); /xml- und Job-Link-Fallbacks unverändert. recruitee erhält dieselbe language-Ausgabe + preferred_languages (Opts oder Eintrag). Die gemeinsamen Helfer liegen in server/lib/language-preferences.mjs.

Hinweise

  • Hand-offs festgehalten, bewusst nicht getan: der Seen-Filter des RU-Scanners ist nicht sprachbewusst, und noch kein RU-Board liefert Zeilen je Sprache; der clientseitige url-key.js-Mirror und die Verdrahtung der Portals-Routen-Validierung bleiben offen. Tests 7096 → 7203; Register unverändert 125 = 120 EN + 5 RU · 120 Adapter.

[1.265.0] — 2026-11-01

Neu

  • Zwei neue Scan-Quellen — Apple und Bulldogjob (Register 123 → 125 = 120 EN + 5 RU · 120 Adapter) — Parent-Sync-Welle gegen career-ops @ fe857ecf. Apple (jobs.apple.com, #5496 + #6196): die Seite ist eine React-Router-SSR-App ohne brauchbare JSON-API, daher liest die Quelle den Hydration-Blob der gewöhnlichen Suchroute (window.__staticRouterHydrationData); die Ermittlung steuert der Eintrag (apple.queries nach Relevanz sortiert + apple.teams-Slug-Achsen, keine Defaults — ein Eintrag ohne beides wirft), die Seiten sind durch max_pages begrenzt (Standard 2, Deckel 50) mit 200-ms-Pacing, jedes URL-Segment wird surrogate-sicher kodiert, und eine Stellung, die Apple als PIPE markiert, trägt im Snippet den Hinweis «kann ein Talent-Pipeline sein» — danach wird nicht gefiltert. Bulldogjob (bulldogjob.pl, #6253): das polnische Tech-Board hat ebenfalls keine JSON-API — die Listing-Seiten tragen __NEXT_DATA__ (50/Seite, totalCount); der careers_url des Eintrags ist die auf der Seite gebaute Suche (die Filter leben im Pfad), jede Anfrage trägt ein explizites /page,N, und der Walk hält bei einer kurzen Seite, dem gemeldeten Total oder max_pages (Standard 25, Deckel 100) mit Truncation-Tag auf Teilboards.
  • IBM-Pagination-Rework (#6273) — der feste 600-Record-Walk wird zu max_pages (Standard 20, Deckel 300, Override je Eintrag) mit 200-ms-Pacing zwischen Seiten und Retry pro Seite über fetchJsonWithRetry; eine fehlgeschlagene erste Seite wirft, eine fehlgeschlagene spätere behält das Gesammelte und benennt die Seite, und nur eine volle Seite am eigenen Deckel des Eintrags warnt «raise max_pages».

Behoben

  • justjoin datiert Angebote nach lastPublishedAt (#6254) — das publishedAt der Kandidaten-API rückt bei jeder Aktualisierung durch den Arbeitgeber vor, sodass der Großteil des Boards das heutige Datum trug und max_posting_age_days Wochen alte Angebote durchließ; jetzt gewinnt das frühere Publikationsdatum, mit Fallback, wenn es fehlt oder sich nicht parsen lässt.
  • jobvite faltet Zeilen, die einen Posting-URL teilen (#6127) — ein öffentlicher Feed liefert eine <job>-Zeile pro Stadt für einen einzigen Detail-URL; der Parser behielt die erste Stadt und zählte den Rest als Duplikate. Nun tragen Geschwister nur Orte bei, in Feed-Reihenfolge mit · verbunden, erster Titel/datum bleibt, und remote wird über den verbundenen Ort neu bewertet.
  • Liveness: ein UltiPro-Rung (#6090) — UKG hat keinen Per-Posting-JSON-Endpoint und antwortet auch auf geschlossene mit 200, sodass alle 57 geschlossenen UltiPro-Stellungen uncertain lasen. Die Detailseite bettet den Datensatz ein: OpportunityIsClosed true/false → expired/active, der Hinweis «opportunity unavailable» → expired, alles andere bleibt beim Browser. Built Ins Banner „Sorry, this job was removed” wird hard-expired (#6336) — die Seite behält den vollen JD und die APPLY-Steuerung; nun gewinnt das Banner, und ein Geschwister-„Job removed”-Badge ohne „sorry” matcht nicht.

Hinweise

  • Bewusst nicht getan: die Parent-Seite der Jobvite-Fixes zum Location-Compiler von scan.mjs (web-ui dokumentiert den USPS-Compiler als No-Port) und das note-Feld des Parents für Apples PIPE-Hinweis (web-uis Job-Shape hat kein note; es reist im snippet). Tests 7096 → 7135 (+39); Playwright 173 pass / 0 fail / 1 opt-in skip; Coverage-Gate ≥ 98/89; Register 125 = 120 EN + 5 RU · 120 Adapter (alle Zähl-Gates aus dem lebenden Register regeneriert).

[1.264.3] — 2026-11-01

Behoben

  • Rate-Limit-Härtungswelle (Review-LOW №1–3 aus REVIEW-2026-10-31-v1.264.1) — writeRateLimit() (express-rate-limit@7.5.1, 60 req/min route×IP, 429 JSON + Retry-After) deckt jetzt alle 47 mutierenden Endpunkte ab (waren 2): 9 falsch gescopete llmRateLimit-Guards ersetzt (/api/config — die .env-Neuschreibung!, PUT /api/batch, /api/batch/merge, outcome, followup/seed, assessments, stats/snapshot, mock-interview/save, networking/save), 3 gestapelt vor dem LLM-Bucket auf den teuren Pfaden (/api/evaluate, /api/deep, /api/auto-pipeline), und 33 nackte Registrierungen verdrahtet (CV-/Profil-/Modes-Editoren, alle Tracker-Schreibzugriffe, Pipeline POST/restore/DELETE, jds, die 7 /api/run/* über eine Loop-Änderung, posting-guard, Playwright-PDF inline, portals toggle/health/track, discover, reports, export/docx, two-pager, career-plan, memory und die drei DELETE-Routen). /api/apply-helper bleibt als Allowlist-Fall ohne Rate-Limit (reine lokale Berechnung, gepinnt); 16 reine LLM-Routen behalten den konditionalen LLM-Bucket by design. Ein Vollständigkeits-Tripwire (tests/rate-limit-coverage.test.mjs, red-first bei 27 nackten) lässt CI bei jeder künftigen ungedrosselten mutierenden Registrierung fehlschlagen.
  • TRUST_PROXY-Opt-in + neu bewaffnete Validierungen (Review-LOW №1–2) — app.set('trust proxy', N) respektiert eine TRUST_PROXY-Env als Hop-Anzahl (nie boolean true — das würde auf das Angreifer-kontrollierte linke XFF-Ende keyen); standardmäßig unset, sodass Loopback seine dokumentierte socket-keyed Degeneration pro Route behält. validate: false wird zu einem gezielten writeValidateConfig(): nur xForwardedForHeader ist ausgenommen (Caddys XFF wird ohne Trust Proxy by design ignoriert), jede andere Validierung — inklusive trustProxy — ist wieder laut, sodass eine künftige trust proxy: true-Fehlkonfiguration als ERR_ERL_PERMISSIVE_TRUST_PROXY an die Oberfläche kommt, statt zu verstummen. Der eigene keyGenerator wurde bewusst entfernt: express-rate-limit koppelt seine Proxy-Validierungen an den Standard-Key-Generator, und die Isolation pro Route bleibt unverändert (ein MemoryStore pro Factory-Aufruf).
  • cvstart.org-Kopier-Feedback springt nach 2 s zurück (CAR-141) — der «Скопировано ✓»-Zustand hält jetzt die akzeptanzkriterien-vorgeschriebenen 2 Sekunden (waren 1,5 s), red-first gepinnt in tests/site-copy-feedback.test.mjs. Damit ist das letzte agenten-fixierbare CAR-141-Kriterium geschlossen; die Demo-Video-Aktualisierung bleibt vom Owner vertagt (Entscheidung 2026-11-01).

Geändert

  • Help-Bundles sagen 19 Sprachen (×19) — die §19-„Localizing the app“- und §32-„Run it from OpenWorker“-Sätze hinken nicht mehr zwei Locales hinterher: jedes Bundle sagt jetzt 19 mit தமிழ் und Tiếng Việt im jeweiligen Aufzählungsstil (ar nutzt das ausgeschriebene «التسع عشرة»), und der eigene «cả-17»-Rest in vi.md §32 ist ebenfalls gefixt. Struktur-Gates (33 H2 / 125+ H3) byte-stabil.
  • State-Hygiene — AGENTS.md nennt v1.264.2 / 7082 Tests (war v1.86.x / 1566); PLAN.md markiert die Releases 1–7 als Shipped, und ihr Ship-Train-Absatz sagt docs ×19; der StatsBar.astro-Kommentar beschreibt jetzt, was facts.adapters tatsächlich enthält (123 = Sources-Gesamtzahl, der historische Key-Name bleibt für Konsumenten erhalten); der i18n.js-Header sagt 19 Sprachen; der v1.264.2-QA-Prompt trägt die echte Coverage (98.45/90.05) und die Playwright-Arithmetik (176 = 174 Harness + 1 opt-in-Skip + 2 Script-Level-Suiten).

Hinweise

  • Bewusst nicht getan: die Parent-Sync-Welle gemäß der festgehaltenen Port-Liste bleibt im BACKLOG — der Fork muss erst über Upstream a9476866 hinaus synchronisieren (7 der 10 Port-Listen-Commits sind noch nicht im lokalen Eltern-Baum; IBM/UltiPro/Bulldogjob/apple mit Umfang S–M gescort, personio language-dedup auf ein eigenes Release vertagt). Die erneute Aufnahme des CAR-141-Demo-Videos ist vom Owner bewusst vertagt («видео не надо пока», 2026-11-01).
  • Tests 7082 → 7096 (+9 Coverage-Tripwire + 5 Trust-Proxy); Playwright 173 bestanden / 0 fehlgeschlagen / 1 opt-in-Skip (+2 Chevron-Pins in bestehenden Fällen); Coverage 98.46 Zeilen / 90.10 Branches; Evals 14/0/1skip; Registry unverändert 123 = 118 EN + 5 RU · 118 adapters.

[1.264.2] — 2026-11-01

Behoben

  • Sidebar-Gruppenheader schließen sich dem Kürzungs-Contract an (CAR-219) — die Gruppen-Toggle-Labels (.nav-v2-toggle > span) kürzen jetzt mit Ellipsis und tragen einen lokalisierten Tooltip über denselben syncLabelTitles()-Mechanismus wie die CAR-203-Nav-Items; der Chevron schrumpft nie, der Toggle bleibt klickbar, RTL hält. Red-first-Pin in tests/nav-v2.test.mjs (+1 → 7082 Tests).

Geändert

  • cvstart.org-Texte erscheinen in allen 19 Sprachen (CAR-220) — meta.helpDesc, helpTeaser.c1.desc und faq.a2 sind in jeder Site-Locale übersetzt (in v1.264.1 waren sie by design EN-only); GitHub Pages hat den überarbeiteten Text live auf cvstart.org ausgeliefert.
  • Backlog- und Review-Hygiene (CAR-221/222) — die sechs «Port-when-merged-upstream»-Items sind geschlossen: alle sieben Upstream-PRs sind gemerged, vier Items waren bereits portiert, zwei sind auf der Eltern-Seite. docs/reviews/REVIEW-2026-10-31-v1.264.1.md landet (0 HIGH / 0 MED, drei LOW-Follow-ups im BACKLOG vermerkt), und die Parent-Sync-Port-Liste ist festgehalten (6 PORT / 3 VERIFY / die apple-Source-Lücke; Upstream-Tail 118 Commits @ VERSION 1.38.0).

Hinweise

  • Der Changelog-Mirror-Stamp-Fix (92a05fcf) fährt in diesem Tag mit: jeder paginierte Mirror auf cvstart.org trägt jetzt die generierende Release-Version, sodass der site-build-after-fanout-Grader endlich seine echte Logik ausübt, statt zu überspringen.
  • Bewusst nicht getan: das Drosseln der restlichen mutierenden POSTs (Review-LOW №3) und die Trust-Proxy-Bucket-Kopplung — im BACKLOG für die nächste Härtungswelle vermerkt. CAR-141 (Demo-Video) bleibt beim Owner.
  • Tests 7081 → 7082 (+1 CAR-219-Pin); Playwright 176; Registry unverändert 123 = 118 EN + 5 RU · 118 adapters.

[1.264.1] — 2026-10-31

Behoben

  • Sidebar-Pills kürzen lange lokalisierte Labels elegant (CAR-203) — das Nav-Label-Span ist jetzt ein ordentliches Flex-Mitglied (min-width: 0 + overflow: hidden + text-overflow: ellipsis + nowrap in v2-nav.css), und syncLabelTitles() in nav-v2.js spiegelt das lokalisierte Label über denselben data-i18n-Key in den Tooltip (null neue i18n-Keys) — das lange «Профинансированные компании» ist beim Hover wieder lesbar, statt vom overflow: hidden der Zeile hart abgeschnitten zu werden. Das 44-px-Touch-Ziel, die aktive Färbung und der RTL-Spiegel bleiben unberührt; red-first-Pin in tests/nav-v2.test.mjs.
  • Eine 480-s-Evaluations-Obergrenze für jede Locale (CAR-218) — die Remote-QA von v1.264.0 fing vorübergehende 502 · 300 s · 0 ch-Evaluierungen auf es und zh-CN ab (der Spot-Re-Run lief grün, aber die Wand war real). EVAL_TIMEOUT_MS ist jetzt 480_000, und evalTimeoutMs(lang) gibt ihn bedingungslos zurück — GEMINI_EVAL_TIMEOUT_MS und die Auto-Pipeline erben. Das locale-spezifische Token-Budget aus CAR-174 (16384 / 32768) bleibt die einzige pro-Locale-Aufteilung.

Geändert

  • cvstart.org-FAQ trägt exakte Source-Zählungen (CAR-217) — {sources} job-board sources: {sourcesEn} international boards plus {sourcesRu} Russian ones wird aus facts.json substituiert, das aus der Live-Registry erzeugt wird (123 = 118 EN + 5 RU), sodass die Zahlen nie driften können; Locales mit der älteren ~{adapters}-Formulierung runden weiter über adaptersRounded. EN-Textverbesserungen fahren mit: meta.helpDesc, helpTeaser.c1.desc und faq.a2 nennen das Befehlsmenü, die gruppierte Pipeline mit Undo und den Kanban-Tracker.

Hinweise

  • Bewusst nicht getan: die Site-i18n-Textverbesserungen (meta.helpDesc / helpTeaser.c1.desc / faq.a2) bleiben in diesem Release EN-only — andere Locales behalten ihre korrekte, aber runder formulierte Fassung bis zur nächsten Docs-Welle (ihr faq.a7 bekommt die Exaktzahl-Platzhalter, wo übersetzt). CAR-141 (Demo-Video) bleibt beim Owner; der überholte Zweig car136/m141 wurde gelöscht, seine Ideen sind im Linear-Task festgehalten (wiederherstellbar über den Tag archive/car136-m141).
  • Tests 7041 → 7081 (CAR-203-Pin + CAR-218-Pin-Rewrites); Playwright 176; Registry unverändert 123 = 118 EN + 5 RU · 118 adapters.

[1.264.0] — 2026-10-31

Hinzugefügt

  • Inline-Bearbeitung des Tracker-Status — das Status-Badge jeder #/tracker-Zeile ist ein kompaktes <select> der kanonischen Stufen (aus GET /api/tracker/stages, nie eine hartcodierte Whitelist). POST /api/tracker/status reicht an das kanonische set-status.mjs des Elternprojekts weiter, unter der applications.md-Sperre (Status-Whitelist via states.mjs, --dry-run/--note-Durchreichung, fail-soft 502 mit bereinigtem Detail, argv-Array-Spawn). Erfolg aktualisiert die Zeile an Ort und Stelle (Tone-Klasse + Tab-Zählungen, Fokus bleibt); Versagen macht rückgängig und zeigt einen Toast. Zeilen, die das Relay nicht adressieren kann — ein handeditierter unbekannter Status, ein Backfill-Sentinel # — behalten das schreibgeschützte Badge (Route-Review-LOW-Fixes; Reviewer: keine HIGH/MED-Funde).
  • Server-Warnungen auf jeder KI-Seite sichtbar — evaluate, deep, auto-pipeline (Seite und Modal), career-plan, market, cv-studio (humanize + tailor) rendern jetzt das warnings-Array des Servers (Output-Token-Kürzung, Sprachdrift, Datumskorrekturen) als badge-warn-Band (role="status"); das Auto-Pipeline-Modal verwirft die Done-Frame-Warnungen nicht mehr. Neuer Key llm.truncatedNotice ×19.
  • Coverage-Welle (+111 Tests) — routes/map.mjs 100/94.9, geocode.mjs 96.3/92.9, content.mjs 99/84.9, networking.mjs 96.4/89.1, sources/habr.mjs 100/98.2 (neu tests/cov-*-routes.test.mjs ×3, tests/sources-habr.test.mjs); Branch-Boden bei ≥ 90 % gehalten.
  • Linear CAR-191…216-Abschlussbündel (docs/reviews/2026-10-30-linear-car191-216-closure-bundle.md) — einfügebereiter Owner-Abschluss mit Commit-SHAs pro CAR und Beleg-Kommentaren.

Behoben

  • Trudvsem-Scan-Quelle — eine leere Seite (results: {}, auch „hinter dem Ende”) killt nicht mehr den ganzen Scan (sauber null Zeilen); API-Fehlerumschläge (HTTP-200 mit status: 500) werfen mit dem eigenen Text der API; die Paginierung läuft in Record-Offsets (war Seiten-Index — Seiten wurden stillschweigend dupliziert, ~52 Stellen statt Hunderten); der Walk stoppt vor der Deep-Offset-Fehlerzone der API (offset × limit ≥ 10000). Live end-to-end verifiziert.
  • habr — Titel/Firmen werden nach der Entity-Dekodierung von Tags befreit (hh.mjs-Parität): &lt;script&gt; in einem Karten-Titel erreicht die Scan-Zeilen nicht mehr als lebendes Markup; legitime >> in Titeln überleben.
  • PUT /api/profile (Raw-Pfad) — ein candidate:-Block ohne nicht-leeres full_name wird abgewiesen, gleiche Linie wie der Felder-Merge-Pfad (er persistierte früher full_name: null).
  • Ehrliche Hints — .doc aus der CV-Upload-Accept-Liste und aus cv.uploadHint ×19 entfernt (der Parser unterstützte es nie); config.openaiModelHint ×19 nennt gpt-5 (der Server mappt jede *-codex-ID darauf); config.anthropicModelHint ×19 und der Anthropic-Default spiegeln jetzt die Tiers des Elternprojekts — Default claude-sonnet-5-5, Premium claude-opus-5-5.
  • Claude-Code-Docs-Link → code.claude.com (die alte docs.anthropic.com/en/docs/claude-code-URL wirft im Links-Gate einen TypeError).
  • help ×19: der Row-Density-Bullet ist weg (der Toggle hat die UI in v1.263.0 verlassen) und 18 kaputte **fett**-Span-Familien sind repariert — plus die Renderer-Leak-Klasse ×19 gefixt (zweite Leerzeile nach jeder Tabelle-vor-Absatz; Pipe-Zeichen raus aus den Fett-Zellen): 0 literale ** im Rendering über alle 19 Help-Bundles.

Hinweise

  • Das Anthropic-Standardmodell hat gewechselt auf claude-sonnet-5-5 (der Standard-Tier des Elternprojekts). Deploys, die auf den alten stillen Default (claude-sonnet-4-6) bauten, aktualisieren sich automatisch — ANTHROPIC_MODEL in .env pinnen, um auszusteigen.
  • Bewusst nicht getan: die beiden LOW-Review-Nits, absichtlich offen gelassen (der Inline-Select spiegelt nicht die Kanban-movesReady-Degradierung — der ehrliche Toast bei jedem Fehler ist das gewählte Verhalten; der code: 'timeout'-Zweig bleibt vom Fake-Writer-Vertrag abgedeckt, nicht von einem >30-s-Test). CAR-141 (Demo-Video) bleibt beim Owner.
  • help ×19 hat den Post-Release-Prosa-Durchgang (Density-Bullet raus, Renderer-Leak-Klasse gefixt) auf main bekommen, nachdem v1.263.0 erschienen war — dieses Release ist das erste Tag, das ihn trägt.
  • Auch in diesem Tag: die Basis des Evidence-Chips (Report-Parsers + Ansicht-Badges), der fix-report-links-Runner (POST /api/runners/report-links, Karte „Reparieren“ auf #/health) und die Batch-Kostenschätzung/-bestätigung mit Usage-Aufzeichnung — zwischen Branch-Schnitt und Tag auf main gelandet.

Tests 6905 → 7041 (+136) · Playwright 176 (173 bestanden / 1 opt-in-Skip) · Coverage 98.5 % Zeilen / 90.1 % Branches · Registry unverändert: 123 sources = 118 EN + 5 RU · 118 adapters.

[1.263.0] — 2026-10-30

Hinzugefügt

  • Motion-Polish-Layer — neues motion.css (letztes App-Sheet): Modal-/Popover-Eintritte (scale .97 + Fade, 130–180 ms), Toast-Spring-in + weicher Leaving-Zustand, Theme-Toggle-Press-Feder, Chip/Tab-Press scale(.97), Stagger-Infrastruktur (50-ms-Schritte, Cap 12), .page-enter-Routenwechsel-Fade (Router), Focus-Halo-Übergänge an Chips/Tabs. Jede Regel ist prefers-reduced-motion-sicher (Bewegung fällt auf none, Opacity/Farbe bleiben).
  • Touch-Korrektheit — 68 Hover-Lift-Regeln waren ungeschützt: Touch-Geräte behielten nach einem Tipp eine hängende „angehobene”-Karte. Alle Transform-Hovers sind jetzt @media (hover:hover)-gegated (motion.css-Neutralisierer), und der Karten-Lift greift nur bei wirklich interaktiven Karten (.card:has(a), a.card, button.card, [role=button].card) — keine falsche Affordance mehr auf statischen Karten.
  • A11y: jede Kontrolle hat einen programmatischen Namen. Ein neuer A11yDump-Helper benennt alle 16 Readonly-LLM-Output-Dumps; 12 Placeholder-only-Felder (CV Studio ×6, config ×2, scan-Suche, tracker-Score-Select, outcome-Notiz, plan-Editor, auto-URL, bug report) bekamen aria-labels; das a11y-form-wires-Gate erzwingt das jetzt klassenweit (vorher 26 unbenannte Stellen, jetzt 0 + Allowlist mit dokumentierten Gründen).

Behoben

  • #/scan: der Sticky-Tabellen-Header übermalt die Topbar-Suche nicht mehr, sobald sie unter ihn scrollt (z war gleich dem der Topbar, das spätere DOM gewann — jetzt token-abgeleitet darunter); die „Зарплата от/до”-Eingaben sind wieder normal groß (eine .v2-scan-bar .input-Flex-Regel lief in den Spalten-Flex des Popovers und setzte flex-basis 200 px als HÖHE — jetzt >-gescopet + Popover-Guard); der Density-Toggle-Button ist auf Eigentümer-Entscheidung entfernt (Verdrahtung bleibt, i18n-Keys entfernt ×19).
  • Deploy-Workflow-Härtung (F1–F6): provider-Input charset-validiert vor jedem Shell-Splice; hermes-Diagnostik schwärzt Werte (case-insensitiver Key-Filter + Wertmaske + 80-Zeichen-Schnitt an allen drei Sinks, ?token= ebenfalls maskiert); der hermes-Schritt respektiert inputs.app_dir; public_url https-gegated; der Anti-Downgrade-Guard hat 6 ausführbare Pins (keine Defaults, Guard-vor-Deploy-Reihenfolge, strict refs regex).
  • Review-Schwanz, red-first: CSV-Import-Backslash-Roundtrip (Re-Import deduplizierte wieder), cv-voice Head-Strip 4827 ms → 13 ms, statedYearsMin lazy berechnet, posting-guard Capture TOCTOU, MiniMax-CN-Wildcard, deel-Token-Skip, Import-Picker-Size-Guards vor dem Lesen. Import-Modal: Nav-Guard scharfgeschaltet, File-Input beim Abbruch entfernt, bewachte Duplikat-Lesevorgänge, num via reduce.
  • Owner-UX-Batch: vertikaler Rhythmus des Dashboard-Hero (Inline-Level-Kinder zu einer Zeilenbox verklebt); help-TOC −8 px Verschiebung der aktiven Zeile (Inline-Gutter pro Zeile + Nummernspalte); mobiler Drawer (sichtbares ✕-Schließen, scrollTop-Reset, der Phantom---paper-Fade auf .has-hud gegated); die docs-assistant-Seite läuft nicht mehr über mit einer langen URL in einer Antwort (Grid-min-width-Kette + overflow-wrap: anywhere); „Недавние” erklärt (Hinweis) + löschbar; career-plan Save bewaffnet sich nach einer fehlgeschlagenen Ladung erneut; evaluate URL-Prefill verbrennt keinen LLM-Aufruf mehr auf dem Paste-Platzhalter; auto-pipeline Enter respektiert die IME-Komposition.
  • Kontrast (WCAG-Audit, 296 Paare): docs-fab-Gradient 2.43 → 6.4:1, toast.success → ok-soft-Paar (1.75 → AA dark), Banner btn-dark → --ink-Flip, scan-logbtn/reposts-badge/fab-chip/close helle Varianten, und Formular-Kontrollränder auf 3:1 (--cv3-input-line, WCAG 1.4.11 — war 1.2:1).
  • Visueller Durchgang: der Tracker-Leerzustand ist eine Karte in voller Breite (war abgeschnitten innerhalb der 760-px-Tabelle bei 390); die Scan-Konsolenzeile ellipsisiert, statt halb abgeschnitten zu werden; der schwebende Chat-FAB verdeckt bei 390 keinen Inhalt mehr (44-px-Ziel, inset 12); der Dashboard-„Application statuses”-Leerzustand folgt dem v2-empty-Muster; der stats-„?“-Hinweis bekommt einen Teiler + 44-px-Ziel; der career-plan Input-Tab erklärt, wo das Ergebnis landet; help §1 Markdown (18 kaputte Bold-Spans).

Geändert

  • Akzent Blau → Karmesinrot (Eigentümer-Wunsch, logo-koherent, hue 15) — 5 cv3-Tokens × 3 Theme-Blöcke; der docs-assistant-Chatbubble-Text reitet auf --accent-ink (war literales #fff, 2.39:1 im Dark); der funded-Wash reitet auf --accent-soft. Danger bleibt hue 25 mit seinen eigenen Behandlungen.
  • Docs: README-Testing-Tabellen-Zählung ×17 (eine Drift aus der v1.248-Ära), help §1 + 18 Markdown-Spans, help fr/it/ta „118”, Anbieterpreise CHECKED_ON 2026-10-30, HANDOFF/CONTEXT/TRACEABILITY-Fakten.

Hinweise

  • Bewusst nicht getan: die Skeleton-Sweep-Überarbeitung bleibt draußen (der car112-Vertrag pinnt das aktuelle Fade wörtlich); das Theme-Toggle-Icon-Crossfade bleibt ein display-Swap (der Theme-Toggle-Playwright-Vertrag beobachtet es); das .btn:active-Scale wurde nicht dupliziert (app.css besitzt es); Motion-Stagger ist nur Infrastruktur — die Dashboard-Tiles übernehmen ihn später; help ×19-Prosa (Density-Erwähnung, §1-Markdown, „118”) kommt mit dem nächsten Fan-out.
  • Volle Remote-QA-Beweise: ja Spot grün (376 s / A–G ✓) auf v1.262.4; en/it früher in der Token-Dense-Ära grün.

Tests 6869 → 6905 (+36) · Playwright 176 · Coverage 98.4 % Zeilen / 89.9 % Branches · Registry unverändert: 123 sources = 118 EN + 5 RU · 118 adapters.

[1.262.4] — 2026-10-30

Behoben

  • ja stößt zu den token-dichten Bewertungs-Locales hinzu (ja → das 32768-Token-Ceiling + die 480 s Uhr). Der 5-Locales-Spot-Nachlauf auf der Prod v1.262.3 trennte die vier 502 · 300 s · 0 ch-Timeouts der Nacht in transiente und deterministische: ar (250 s), ko (291 s) und zh-CN (259 s) bestanden ihre Reruns, die einmalige Sprachdrift von ru wiederholte sich nicht — aber ja stieß zweimal mit null Output an die Standard-Schranke (der volle ×19-Lauf 40981578549 und der Spot-Lauf 41012725839). Dieselbe Formklasse wie it/pl. Red-first-Pin: evalMaxTokens('ja') = 32768, evalTimeoutMs('ja') = 480_000, die anderen Locales behalten 300 s.

Hinweise

  • Bewusst ein Single-Purpose-Patch: der ja-Fix ist die einzige Änderung, die dieses Release mitbringt — es kommt nichts anderes mit. ar/ko/zh-CN bleiben auf dem Standard-Ceiling aufgrund der Beweise von heute Nacht (sie bestehen; die Fehler der Nacht waren transiente Provider-Last), und die Drift von ru war ein einmaliger Generierungs-Flake.

Tests 6868 → 6869 (+1) · Playwright 176 · Registry unverändert: 123 sources = 118 EN + 5 RU · 118 adapters.

[1.262.3] — 2026-10-30

Behoben

  • pl stößt zu den token-dichten Bewertungs-Locales hinzu (pl → das 32768-Token-Ceiling + die 480 s Uhr). Das volle Remote-QA auf der Prod v1.262.1 hat die polnische Bewertung beim Sterben am Standard-Ceiling ertappt — 502 · openrouter · 300 s · 0 ch — und der mit v1.262.2 ausgelöste Spot-Nachlauf reproduzierte sie exakt (die Läufe 40960568766 und 40968958062): 18/19 Locales bestanden A–G, it endete nach 302 s innerhalb der token-dichten 480 s Uhr, und pl lief zweimal mit null Output gegen die Wand. Ein deterministischer Timeout, kein Flake — dieselbe Formklasse, die it in v1.262.1 bewegt hat. Red-first-Pin: evalMaxTokens('pl') = 32768, evalTimeoutMs('pl') = 480_000, die 18 Standard-Locales behalten 300 s.

Hinweise

  • Bewusst ein Single-Purpose-Patch: der pl-Fix ist die einzige Änderung, die dieses Release mitbringt — er bringt nichts anderes mit; der Review-Tail-Inhalt von v1.262.2 ist separat erschienen.

Tests 6867 → 6868 (+1) · Playwright 176 · Registry unverändert: 123 sources = 118 EN + 5 RU · 118 adapters.

[1.262.2] — 2026-10-30

Behoben

  • Wave-Review-Tail — 7 Befunde geringer Schwere, jeder red-first. Der CSV-Import-Backslash-Roundtrip: ein \ in einer Zelle wurde doppelt geschrieben und doppelt zurückgelesen, sodass der erneute Import derselben CSV das Firmen+Rollen-Dedup verfehlte und eine Dublettenzeile erzeugen konnte — der Reader entwandet \\ jetzt nach dem Split (der Schreiben→Lesen-Roundtrip ist verlustfrei, der Re-Import dedupliziert). Das cv-voice-<head>-Stripping war quadratisch bei ungeschlossenen Tags — 4827 ms → 13 ms auf der 64-KB-Eingabe, mit der die Route deckelt. statedYearsMin fuhr den vollen Years-Parser für jede Stelle jeder Quelle, selbst wenn years_min nicht konfiguriert war — jetzt lazy, die CPU-Sekunden pro großem Scan sind weg. Ein zwischen readdir und statSync gelöschtes Capture ließ das Posting-Guard-Listing abstürzen (TOCTOU — verschwundene Dateien werden übersprungen). Der MiniMax-CN-Default matchte nur exakt api.minimax.cn — jede *.minimax.cn-Basis-URL bekommt jetzt das CN-Modell. Deel-$-Tokens, die keine Hex-Refs sind, lecken nicht länger als Literale in den Snippet. Der Import-Picker prüft file.size VOR file.text() — das 512-KB-Server-Limit antwortete mit 413 erst, nachdem der Browser eine möglicherweise riesige Datei geparst hatte — mit einem lokalisierten import.tooLarge-Toast ×19.
  • Deploy-Workflow-Härtung (Workflows-Review F1–F6). provider war die einzige Eingabe, die ohne Zeichensatz-Validierung in die Remote-Shell interpoliert wurde — ein ' im Wert brach aus dem Quoting aus und führte beliebigen Code auf der Prod aus; jetzt wird vor jedem Splice auf die Whitelist ^[A-Za-z0-9_-]+$ geprüft, und der Key-Guard-grep kann nicht mehr fälschlich durchgehen. Der Hermes-Diagnose-Schritt druckte rohes journalctl + Unit-Dumps ins öffentliche Log; sein Filter verfehlte großgeschriebene *_API_KEY= und maskierte nichts — jetzt ein gemeinsamer case-insensitiver Redact + Wert-Masking + 80-Zeichen-Kürzung an allen drei Sinks, auch ?token=-Query-Strings werden maskiert. Der Hermes-Schritt ignorierte inputs.app_dir und hardcodete /opt/career-ops/src/.env. public_url erreichte curl ohne https-Prüfung (Option-Injection über ein führendes -). Und der Anti-Downgrade-Guard — der Fix des v1.238.0-Vorfalls — hatte kein ausführbares Gate: sechs neue Pins in ci-workflows (Refs haben keine Defaults, der Guard läuft vor Deploy, strenge Refs-Regex).
  • Import-Modal-Tail (SPA-Review). Das Modal aktiviert denselben Nav-Guard wie das Outcome-Modal — ein Wegnavigieren hinterlässt es nicht mehr verwaist über einer anderen View. Das versteckte Datei-Input wird bei cancel entfernt, nicht nur bei change — wiederholtes Verwerfen leakt keine Inputs mehr in document.body. plan.duplicates wird in der Preview über die bewachte Form gelesen. Die Tracker-num-Allokation nutzt reduce statt Math.max(...spread) — der Spread stößt bei ~100k Zeilen an das Argument-Limit.

Geändert

  • Docs: der «118 EN adapters»-Bullet des Hilfe-Guides trägt die Zahl jetzt auch in fr/it/ta (die anderen 15 Locales hatten sie bereits). Die Vendor-Preise auf cvstart.org wurden gegen die offiziellen Pricing-Seiten nachgeprüft — alle vier unverändert, CHECKED_ON → 2026-10-30. Ein Post-Release-Drift-Sweep korrigierte 42 veraltete Zahl/Version-Zeilen über README ×19, CONTEXT.md, CLAUDE.md und die SDD-Handbücher (Überbleibsel der 109/104-Ära und der v1.262.0-Ära).

Hinweise

  • Bewusste Nicht-Aktion: das native window.confirm des cv-studio (Ära CAR-179) bleibt — die Umstellung auf UI.confirm ist ein Follow-up, kein Patch-Posten; der <mark title>-Floskel-Tooltip bleibt nur Tooltip (akzeptable A11y-Untergrenze); remote-qa.yml behält cancel-in-progress: true — eine erneute Auslösung ersetzt eine laufende Regression bewusst.
  • Volles Remote-QA auf der Prod v1.262.1: Routen ×19 ✓ · Site ×19 ✓ · Links ✓ · Live-LLM 18/19 Locales A–G ✓ — pl traf ein einzelnes 502 · 300 s · 0 ch-Provider-Timeout (kein token-dichtes Terrain; der Spot-Nachlauf reist mit diesem Release).
  • Tests 6841 → 6867 auf dem Release-Branch (6864 pass / 0 fail / 3 skip, +26 vs v1.262.1) · Playwright 176 · Coverage 98.42 % Zeilen / 89.94 % Branches · Registry unverändert: 123 Quellen = 118 EN + 5 RU · 118 Adapter.

[1.262.1] — 2026-10-29

Der Italienisch-Bewertungs-Patch: it stößt zu den token-dichten Locales hinzu (32768-Token-Ceiling + 480 s Uhr), nachdem die OpenRouter-Ära es dabei ertappt hat, den Bericht direkt vor dem SCORE_SUMMARY-Block abzuschneiden — und das Provider-Wechsel-Werkzeug, das diese Diagnose erst möglich machte, kommt im Deploy-Workflow an.

Behoben

  • it-Bewertung vor SCORE_SUMMARY abgeschnitten (CAR-190-Tail): Remote-QA 40928864980 (erster Lauf mit den wieder aufgefüllten Credits) — eine it-Bewertung lief 264 s und kam mit 15 045 Zeichen zurück, tok ~15635 am 16-384-Ceiling: Blöcke A–G intakt, ---SCORE_SUMMARY--- weg. Dieselbe Formklasse, die ta in v1.261.1 (CAR-174) ihr Ceiling eingebracht hat. it stößt zu TOKEN_DENSE_EVAL_LOCALES (ta, hi → ta, hi, it): Sowohl das 32-768-Token-Budget als auch die 480 s Uhr greifen jetzt, und /api/evaluate + Auto-Pipeline bleiben bei der einen Quelle der Wahrheit in llm.mjs.
  • en-Bericht ohne Blöcke — ein einmaliger Generierungs-Flake: Derselbe Lauf sah eine einzelne en-Bewertung sprachrichtig zurückkommen, aber ganz ohne die A–G-Blöcke; ein gezielter Nachlauf lief sauber durch (21 091 Zeichen, A–G ✓). Nicht in den token-dichten Satz aufgenommen — ein Flake ist keine Historie.

Hinzugefügt

  • Deploy-Workflow: mode=hermes und mode=provider (CAR-190-Ops-Tail): mode=hermes startet das Hermes-Gateway neu und druckt eine vollständige Diagnose (Unit-Datei mit entfernten Secrets, Listener vorher/nachher, sudo-Journal, Port-für-Port-Sonden, die eigene HERMES_BASE_URL-Sicht der App, OpenRouter-Credits-Saldo); mode=provider wechselt LLM_PROVIDER mit einem Key-Präsenz-Guard (verweigert, wenn der *_API_KEY des Ziel-Providers fehlt) und startet die App neu — so wechselte die Prod auf openrouter, als die Hermes-Credits im Flug ausgingen. Der Deploy-Mode-Ref-Guard wird nur für mode=deploy validiert, damit Recon-/Verify-Dispatches wieder funktionieren (die Required-Inputs-Änderung aus der v1.261.3-Ära hatte sie verstummen lassen).

Hinweise

  • Bewusste Nicht-Aktion: en kommt nicht in den token-dichten Satz — ein Bericht ohne Blöcke ist ein Generierungs-Flake, keine Volumen-Historie.
  • Bewusste Nicht-Aktion: die verstärkte Ta-Sprachdirektive wird nicht auf it ausgeweitet — für Italienisch wurde kein Sprachdrift beobachtet.
  • Bewusste Nicht-Aktion: die Aufnahme des neuen UI-v2-Demovideos bleibt beim Owner (CAR-141) — die Landingpage bettet inzwischen ohnehin über youtube-nocookie.com ein.
  • Tests 6841 → 6841 auf dem Release-Branch.

[1.262.0] — 2026-10-29

Das Upstream-Features-Minor: die Deel-Jobboard-Quelle stößt zum Scanner (Registry 123), der CSV-Import eines fremden Trackers landet direkt in #/tracker, der Posting-Guard-Integrity-Check und der CV-Voice-Check kommen als Relays/Lints, der Scanner lernt einen Years-of-Experience-Filter, und Apply-Buttons in sieben weiteren Sprachen lesen nicht mehr als fehlend — dazu ist MiniMax’ ausgedientes Default-Modell ersetzt und Reposts werden nicht mehr über Quellen hinweg fabriziert.

Hinzugefügt

  • Deel-Jobboard-Quelle (CAR-184): Registry 123 Quellen = 118 EN + 5 RU · 118 Adapter — erkennt jobs.deel.com/<slug>-Tenant-Boards automatisch (Klarna und andere); das Next.js-Flight-Payload trägt das gesamte Inventar in einer Anfrage (Titel, Standorte, Arrangement, Daten, Beschreibung), der unzulässige /api/-Pfad wird nie berührt, ein Tenant, der Karrieren woanders ausliefert, antwortet mit einem Redirect, den die Quelle beim Namen ablehnt, und die Vergütung bleibt bewusst unmapped (Beträge ohne Pay-Intervall wären eine Schätzung); Count-Gates ×5 + Hilfe §17 ×19.
  • Tracker-CSV-Import (CAR-181): POST /api/tracker/import-csv mit Dry-Run-Preview und gesperrtem Commit — RFC-4180-Quoting, Daten in ISO-/Tag-erst-/Monatsname-Formen, fremde Tracker-Stufen über die kanonischen States gefaltet (eine unbekannte Stufe landet als Evaluated mit Notiz, nie verworfen), Dedup über die normalisierte Posting-URL aus der Markdown-Link-Zelle oder der Notes-Spalte, Limits 512 KB / 2000 Zeilen; #/tracker bekommt einen Import-CSV-Button mit Preview-Modal, i18n ×19.
  • Posting-Guard-Relay (CAR-182): POST /api/runners/posting-guard — das deterministische Zero-LLM-JD-Integrity-Gate des Parent, aufgelöst über die Report-Nummer gemäß der jds/-Capture-Präfix-Regel (gepolstert oder nicht, integer-verglichen) oder einen expliziten, sanitisierten Pfad; das Kind bekommt nur argv, ein 30-s-Ceiling und einen Fail-soft-Vertrag; eine «Posting Guard»-Aktion auf #/reports/:slug rendert die Befunde, i18n ×19.
  • CV-Voice-Check (CAR-188): 27 Floskeln aus Lebensläufen (passionate about, proven track record, leveraged, spearheaded, delve…) plus Bindestrich-Heuristiken (ein Jahresbereich wie 2022–2024 ist kein Anzeichen; 20–30% ist es) als read-only POST /api/cv-studio/voice-check und eine #/cv-studio-Karte, die die exakten Treffer hervorhebt; die Tailor-Checkliste wächst auf sechs Invarianten; i18n ×19.
  • Years-of-Experience-Scan-Filter (CAR-180): der jd-years-Parser (65 Formulierungen, verwirft nie bei Unsicherheit) liest das genannte Minimum aus Stellenbeschreibungen, eine neue years_min:-Portals-Option überspringt unterqualifizierte Postings als skipped_experience (ein beobachtender History-Status, der nie eine URL pinnt), und yearsMin reist im Scan-Snapshot für künftige UI mit.
  • Apply-Controls in sieben weiteren Sprachen (CAR-185/189): Vietnamesisch Nộp đơn ứng tuyển, Bulgarisch Кандидатствай/Кандидатстване/Външно кандидатстване (das Substantiv am Label-Anfang verankert — Ratgeber-Artikel-Links sind kein Apply), Niederländisch Solliciteer/Solliciteren, Spanisch ¡Apúntame!/Postularse (Labels, nicht das Verb — FAQ-Links zählen nicht mehr), Chinesisch 申请职位/投递 (am ganzen Control verankert) — lebende Postings auf diesen Boards lesen nicht mehr no_apply_control.

Behoben

  • MiniMax-Default-Modell (CAR-187): das ausgediente MiniMax-Text-01-Default wird ersetzt durch MiniMax-M3.1-Flash auf api.minimax.io und MiniMax-M3 auf api.minimax.cn; die Basis-URL ist vendor-gepinnt (ein Nicht-Vendor-Host wird zur Laufzeit abgelehnt und der Key erreicht ihn nie); der Settings-Hinweis ×19 nennt die neuen Defaults.
  • Reposts verlangen dieselbe Quelle (CAR-186): eine Rolle, die auf LinkedIn und auf dem Greenhouse des Arbeitgebers gelistet ist, wird nicht länger als Repost gemeldet — Cluster teilen jetzt nach sourceHost(), das regionale Subdomains nur auf bekannten Seiten faltet (de.linkedin.com ≡ www.linkedin.com, aber ca.example.com bleibt getrennt), die Greenhouse-Host-Aliase zu einer Quelle faltet und einen trailing dot entfernt.
  • Sprachdrift der Tamil-Bewertungen (CAR-183): eine verstärkte Tamil-Direktive sitzt jetzt im volatilen Prompt-Schwanz neben dem Volume-Budget (der CAR-174-Slot) — Remote-QA-Reports landen wieder auf Tamil nach dem intermittierenden Drift aus v1.261.2.

Hinweise

  • Bewusste Nicht-Aktion: das Posting-Guard-Relay kommt fail-soft — das Fork-Repo trägt posting-guard.mjs des Parent noch nicht (Upstream PR #6146 ist noch offen), daher antwortet der Endpoint {available:false, reason:"script-not-found"}, bis ein Parent-Sync ihn ausliefert.
  • Bewusste Nicht-Aktion: yearsMin wird in diesem Release nicht als #/scan-UI-Chip sichtbar — das Feld reist im Snapshot, der Filter ist Portals-Config only.
  • Bewusste Nicht-Aktion: die Upstream-Änderungen an Machine Summary in modes/reports (#6161/#6160/#6157) sind nicht portiert — sie kommen mit dem deployten Parent, nicht als web-ui-Mirrors.
  • Tests 6734 → 6841 auf dem Release-Branch; der Dedup-Key des Scanners ist unangetastet (das URL-Normalisierungsverhalten hat sich nicht geändert).

[1.261.3] — 2026-10-28

Der Design-Vervollständigungs-Patch: Lovable-Design Phase 3 (Dichte + vollständige Coral-Ausmusterung), der Scan-Host-Pool (32 Unternehmen, 10 pro Host), sechs Upstream-Provider-Location-Fixes, die Trakstar-Hire-Quelle (Registry 122), CV-Studio-Undo + Wächter für ungespeicherte Änderungen — dazu die Final-Regression-P3-Fixes und die Docs-Parität.

Behoben

  • related-Label der Map-Cluster-Blasen 3,16:1 → 4,68:1 (beide Themes): das helle --map-score-mid auf #567b75 abgedunkelt (das vorgeschlagene #5f7f7a maß nur 4,37 — ein Schritt dunkler war nötig); die Dark-Seite liegt bereits bei 4,98:1, unangetastet. Red-first-Pin in map-cluster-visual.
  • Skip-Link-Fokusring: der letzte literale #ff385c-Outline → var(--accent-c) — alle 78 Fokusringe folgen jetzt dem Akzent-Token.
  • .tab-btn.is-active-Akzent-Topologie (#584, Phase 3): das Control mischte drei Farbfamilien (Coral-Wash + Danger-Text + blauer Rand); jetzt ein einziges Accent-soft-Paar.
  • Upstream-Provider-Location-Fixes ×5 (#580, CAR-176): workday Fully Remote-Flag (kein Ort), workable Telecommuting-Fan-out + State nur ohne Stadt, successfactors nachgestelltes Komma, lever Remote-Wortgrenze, icims Location-präfixierte Labels.
  • http-json: kein Retry nach verbrauchtem Timeout (#580) — ein Deadline-Abort ist in beiden Retry-Helfern nicht-transient (Upstream maß ~94s auf einem Ashby-Board bei 30s×Retries).
  • Docs-Parität (#587): die letzten Zähler aus der 17/18-Ära in HANDOFF/CONVENTIONS/README (uk bekam seine fehlende Локалізація-Sektion; die §-Historie bis §32/§33 erweitert — die 33-H2-Arithmetik verifiziert).

Hinzugefügt

  • Lovable-Design Phase 3 (#584): die Density-Tokens sind live — Tabellenzeilen ≈32px, Controls 30px, Chips 24px (WCAG-2.5.8-Spacing-Ausnahme); jeder Coral-rgba-Rest in cv3-Paare überführt (.dash-hero, .badge-bad, Halos, .tab-btn.is-active); --ease-out deklariert, TOKEN_HANDOFF leer; der .callout--ok/--danger-Vertrag.
  • Trakstar-Hire-Quelle (#583, CAR-177): Registry 122 Quellen = 117 EN + 5 RU · 117 Adapter — host-gepinntes jsapi.recruiterbox.com, Offset-Walk mit Short-/Empty-/Repeated-Stops, Partials bleiben erhalten, trakstarTruncated-Markierung; Count-Gates ×5 + Hilfe §17 ×19.
  • Scan-Host-Pool (#579, CAR-178): bis zu 32 Unternehmen gleichzeitig, gedeckelt bei 10 pro Host (das Keyed-Limiter-Muster des Upstream) — Snapshot byte-identisch zum sequenziellen Lauf (red-first Timing-Mock-Gate).
  • CV-Studio-Undo + Wächter für ungespeicherte Änderungen (#582, CAR-179): begrenzter Undo-Stack (30) über die Ergebnisse der KI-Läufe mit nicht-QWERTY-sicherem Cmd/Ctrl+Z, Wächter vor ungespeicherten Änderungen beim Verlassen der Route (Live-Probe dirty, confirm/rewind/beforeunload), i18n ×19.
  • Upstream-Provider-Fixes ×17 getestet (Teil von CAR-176); die Remote-QA-Zusammenfassung benennt fehlgeschlagene Scan-Quellen + tok ~N pro Eval (#567, bereits in v1.261.2 — die Observability wurde für das Triage dieses Releases genutzt).

Hinweise

  • Der Akzent ist jetzt blau (Lovable-Konzept): primäre Aktionen/aktive Zustände/Fokusringe folgen --cv3-accent; Rot ist dem Danger vorbehalten (.btn-danger, toast.error, Danger-Text). Coral überlebt nur im Logo-PNG-Asset (Owner-Entscheidung).
  • Dichte: Tabellenzeilen ≈32px / Controls 30px / Chips 24px — WCAG-2.5.8-Spacing-Ausnahme dokumentiert; der 44px-Canary aus v1.26.1 wurde auf den Token-Vertrag umgeschrieben.
  • CodeQL: alle 10 offenen Alerts geschlossen (4 als FP dismissed mit Begründung: llmRateLimit/atomicWrite sind dokumentierte Klassen; 6 an der Quelle gefixt).
  • Tests 6655 → 6734 auf dem Release-Branch; außer der neuen Trakstar-Quelle hat sich kein Scanner-Quellen-Verhalten geändert.

[1.261.2] — 2026-10-28

Der Stabilitäts- und Polier-Patch: der Geocode-Cache überlebt einen Absturz mitten im Schreibvorgang (CAR-173), UI.md rendert Listen-Fortsetzungen und verschachtelte Listen, die Key-Lecks im gerenderten Hilfe-Text sind ×17 geschlossen, evaluate bekommt ein sprachabhängiges Token-Limit für ta (CAR-174), der RTL-Chrome spiegelt über logische Properties (85 Funde), die Map-Captures sind ×19 neu gerahmt und die Map-Cluster bestehen den Kontrast im Dark-Theme — dazu die erste Phase der Lovable-Design-Integration (passives tokens-v3.css-Stylesheet), Docs-Backfill (Release-Review + Specs) und CI-Node-Coverage-Ausnahmen.

Behoben

  • Geocode-Cache: Verlust durch zerrissene Schreibvorgänge (CAR-173, #562): beide Flush-Pfade (debounced Insert-Flush, Exit-Flush) schrieben .cache/geocode.json mit einem nackten writeFileSync — truncate-then-write — sodass ein Absturz, OOM oder SIGKILL mitten im Schreiben eine zerrissene Datei hinterließ und beim nächsten Boot das JSON.parse warf und damit stillschweigend den gesamten persistenten Cache (Wochen an Nominatim-Budget) verlor, nicht nur den des Tages. Beide Schreibstellen laufen jetzt über file-lock.mjs::atomicWrite (Temp-Datei im selben Verzeichnis → Rename → Unlink bei Fehlschlag) — derselbe Vertrag, den FULL-R1/FULL-M1 auf pipeline.md, cv.md, profile.yml, career-plan, Batch-Eingabe und Memory angewandt haben. Die CAR-142-Flush-Maschinerie selbst (debounced Insert-Flush, Exit-Flush, begrenztes Herunterfahren) wurde red-first intakt verifiziert: Tests (a)/(b) nageln fest, dass Inserts innerhalb des GEOCODE_SAVE_MS-Fensters die Datei erreichen und diese gültiges JSON bleibt; (c) ist ein Mechanismus-Gate plus verhaltensbasierte Läufe beider Flush-Pfade, die keine Temp-Reste und eine parsbare Datei sicherstellen.
  • UI.md Listen-Fortsetzung (#563): der Listen-Handler verschlang nur direkt aufeinanderfolgende - /* -Zeilen, sodass eine eingerückte Fortsetzungszeile nach einem Bullet aus dem emittierten <ul> herausfiel und der Absatz-Durchlauf den Chunk übersprang — die Fortsetzung sickerte als roher Prosatext mit literalen **-/Backtick-Markern durch (~95 hängende Durchläufe pro Locale über die Hilfe-Bundles; en.md 95, ru.md 104). Eine Fortsetzungszeile — führender Whitespace, kein neuer Block (Überschrift, Bullet, NUL-umhüllter Fence-Platzhalter, Leerzeile) — schließt sich jetzt dem vorherigen <li> als mit <br/> verbundenem Text an, wobei inline() pro Zeile läuft, damit Hervorhebungs-Marker sich nie über die Verbindungsstelle hinweg zu einem Paar finden; der Fence-Platzhalter-Guard prüft NUL als erstes Zeichen, nicht einen nackten Token-Vergleich. Verschachtelte --Bullets, nummerierte Listen, Fences in Listen und Überschriften in Listen bleiben eine dokumentierte separate Lücke (nächste Docs-Welle).
  • Hilfe: Key-Lecks im gerenderten Text ×17 (#561): Remote-QA fand 85 rohe i18n-Schlüssel, die im gerenderten Hilfe-Text sichtbar waren (Ursache repro-belegt: derselbe UI.md-Einzeilen-Bullet-Verzehr — eine umgebrochene Fortsetzung wurde als Rohtext emittiert und behielt ihre Backticks literal; die v1.260/261-Hilfe-Abschnitte schrieben mehrzeilige Bullets). 163 Bullets wurden ×17 Locales auf eine Zeile entfaltet — nur Whitespace, kein einziges übersetztes Wort angerührt (alt gegen neu verifiziert). Ein neues Gate tests/help-rendered-keys.test.mjs rendert jedes Bundle durch die echte Kette (stripGithubOnlyBlocks + vm-geladenes UI.md) und scheitert, sobald einer von 1.711 Schlüsseln im Text auftaucht; red-first 17 Locales → grün. Repro-Werkzeug liegt im Repo: scripts/remote-qa/help-render-scan.mjs (vm) + help-render-crosscheck.mjs (echtes DOM).
  • Remote-QA: Ctrl+K prüft den CAR-122-Palette-Vertrag (#561): prod-regression.mjs erwartet jetzt nach Ctrl+K die Befehlspalette (.nav-v2-palette[role=dialog] + Fokus in nav-v2-input) ODER als Fallback den Legacy-Suchfokus, statt stillschweigend beides zu akzeptieren; der Unit-Test tests/remote-qa-ctrl-k.test.mjs nagelt 6 Szenarien auf einem Mock-DOM fest, red-first 0/6 → 6/6.
  • Map-Capture-Rahmung ×19 (#560): Owner-Meldung zu images/job-map-en.png — oben die halbe Topbar-Suche + ein abgeschnittenes h1, am rechten Rand ein grauer Streifen der Seitenliste, nahe London ein vom Rahmen angeschnittener Marker-Cluster und eine weiße horizontale Linie quer über die Karte bei ~2/3 Höhe. capture-map-screenshots.mjs wartet jetzt auf die Entleerung der Geocode-Queue (located + noLoc === total, nicht der N/N-Zähler — Remote-Zeilen sind strukturell ohne Ort, sodass die alte Wartebedingung nie erfüllt sein konnte), versteckt header.topbar und #notif-drawer für die Aufnahme, clippt exakt die .job-map-page-Box (kein Panel wird mehr vom Rahmenrand angeschnitten), zoomt zwei Stufen heraus, sodass kein Cluster halb angeschnitten sitzt, nagelt die Map-Höhe fest und nimmt einen schlichten Viewport-Screenshot auf (captureBeyondViewport resampelt die kompositierte Tile-Ebene und malt weiße Streifen an Tile-Zeilengrenzen), und richtet den Map-Container auf ganze Pixel aus. Alle 19 Job-Map-Captures neu geschossen.
  • Map-Cluster-Blasen — Dark-Theme-Kontrast + Label-Fit (#572): Owner-Sweep P2/P3 — die Cluster-Ringe des Dark-Themes saßen auf einer festen weißen Füllung (1,83:1); die Ringe nehmen jetzt var(--paper) mit Ziffern aus der Score-Palette (gemessen 4,98:1+, gefüllt 9,53:1; das unterste Band ist auf Dark mathematisch nicht einfärbbar und hält über einen ehrlichen data-dim-Pfad 6,1:1), und das related-Label passt in seine Blase (rAF-Font-Fit, Zahlen schrumpfen nie).
  • #/scan-Sprachwechsel — Skeleton-Re-Arm (#534-Follow-up, Agent unterwegs, landet vor dem Tag): Nacharbeit am v1.261.0-Owner-Fix (#534) — die beim Repaint des Sprachwechsels neu aufgezogenen Skeletons überleben einen abgeschlossenen Re-Fetch nicht mehr.
  • Docs-Drift (CAR-139, Agent unterwegs, landet vor dem Tag): README-×19-Zähler, HANDOFF ×19, CONVENTIONS-Fakten mit dem live-Registry-/Testzustand resynchronisiert.

Hinzugefügt

  • Release-Review + Spec-Backfill (Docs, #559/#558): docs/reviews/REVIEW-2026-10-28-v1.261.1.md (die v1.261.0/v1.261.1-Welle gegen ihre Specs geprüft) und der SDD-Spec-Backfill für dieselbe Welle — das Ende des BACKLOGs benennt jetzt die verbleibende Lücke (dedizierte Tests für sources/habr.mjs).
  • RTL-Deep-Sweep (#571): ein AR-Harness geht 39 Routen × LTR-gegen-RTL ab (X-Spiegelung, Overflow, Clipping, text-align-Signaturen) — 85 Funde behoben: der fixe Chrome (Toast, Sidebar, Drawer + sein Verwerfen-×, Docs-FAB, Usage-HUD, Skip-Link) auf inset-inline-*/border-inline-* umgestellt, Tabellen auf text-align: start/end über 17 View-Dateien + 2 Libs, das pauschale [dir=rtl] text-align:right entfernt (es kämpfte mit der Zentrierung der Scan-Sternspalte), die CAR-58-Score-Spalten-Isolation auf ein ltrNum-Span verlagert.
  • Keyboard-a11y-Harness (#570): tests/playwright-a11y-keyboard.mjs geht 11 Routen ab (Tab-Reihenfolge/Fallen, Fokus-Indikatoren, Escape-Overlays, Enter/Space) — 0 Produktionsdefekte; die Regressionsabdeckung ist neu.
  • i18n-Sweep gegen Unübersetztes (#565): 36 en-identische Werte ×9 Locales übersetzt (*.rolePh, Config-Schlüssel, ta-Manifesto) + ein Sweep-Guard über eine geschlossene Allowlist; Site-i18n-Audit (cvstart.org, #568): 20 Schlüssel × 18 Locales übersetzt (der ganze demo.*/stats.t.*/showcase.tab*-Block war überall Englisch), 1 toter Schlüssel ×19 entfernt.
  • Remote-QA-Observability (CAR-175, #567): die Zusammenfassung benennt fehlgeschlagene Scan-Quellen (stderr samples, redact-before-truncate) und druckt tok ~N aus der Provider-Nutzung; die Logik liegt in einem reinen summary-parts.mjs mit einem Drift-Gate.
  • UI.md verschachtelte Marker-Listen (eine Ebene, #564): --Bullets rendern als verschachteltes <ul> (fence-platzhalter-sicher) — die letzten 2 hängenden Prosa-Durchläufe pro Locale sind weg.
  • Lovable-Design-Integration — Phase 1 (#566) / Phase 2 (Branch, landet vor dem Tag): public/css/tokens-v3.css portiert das Lovable-Konzept wortgetreu (oklch-Oberflächen 0–3, AA-kommentierte Ink-Paare, Akzentfamilie, ok/warn/danger/info/neutral soft+ink, Score-Bänder A–G ×2 Themes, Density + Fokus + Schatten); Phase 2 aktiviert sie unter den bestehenden Token-Namen (Akzent in Blau/Danger gespalten, Score-Bänder + Callouts auf cv3-Tokens) mit aktualisierten Kontrast-/Rollen-/Dark-Gates.
  • Evaluate sprachabhängiges Token-Limit (CAR-174, #569): evalMaxTokens(lang) — ta/hi fragen 32768 an (die drei SDK-Clients klemmten erneut auf 16384; beide Ebenen gefixt), dazu ein Tamil-Volumenbudget im Prompt (≤5 Sätze pro Block, ≤900 Wörter) — der ta-Report der v1.261.1-Remote-QA wurde am Output-Token-Limit abgeschnitten (Block B–G + SCORE_SUMMARY fehlten).
  • CodeQL echtes-Fix-Nachziehen: das neue QA-Render-Werkzeug ersetzte handgestrickte Entity-Behandlung durch strukturelle Split-Durchläufe + htmlToText({cap: Infinity}); Redact-Assertions nageln die exakt maskierte Ausgabe fest; ungenutzte Konstanten des RTL-Harness entfernt.
  • Coverage-Ausnahmepolitik für CI-Node-Varianz (habr #558, states #561): sources/habr.mjs (CI-Node-Matrix-Branch 87,23 gegenüber lokal ≥89) und states.mjs (CI 86,49 gegenüber lokal ≥89) schließen sich den Ausnahmen in scripts/coverage-baseline.json an — Dateien, deren in CI gemessene Branch-Coverage wegen Node-Versions-Varianz strukturell unter der lokalen Untergrenze liegt, werden ausgenommen, statt das ganze Gate herunterzusetzen.

Hinweise

  • Ctrl+K-Vertrag (CAR-122): der Chord öffnet die Befehlspalette — er fokussiert NICHT direkt die Suchbox; der Fokus auf die Suche kommt aus der Palette. Die Remote-QA-Prod-Regression prüft genau dies jetzt ab (#561).
  • CodeQL-FP-Dismiss ×5: die js/missing-rate-limiting-Alerts auf main warten auf den security_events-Token — Operator-Aktion, keine Code-Änderung.
  • Nach dem Branch-Schnitt gelandet: #561/#562/#563/#564/#565/#566/#567/#569/#570/#571/#572 sind allesamt nach main gemerged; die #534-Skeleton- und CAR-139-Agents mergen vor dem Tag. Verschachtelte Marker-Listen über eine Ebene hinaus und inline-lastige View-Geometrie bleiben dokumentierte Lücken.
  • Tests 6609 auf dem Release-Branch (+15 seit v1.261.1; ~13 mehr aus #561 beim Merge — 2 neue Gate-Dateien); die einzigen roten Tests vor dem Fan-out sind die CHANGELOG-×19-Parity-Gates (das Locale-Fan-out ist der nächste Schritt des Orchesters); keine Scanner-Quellen angefasst (Registry 121 = 116 EN + 5 RU · 116 Adapter).

[1.261.1] — 2026-10-28

Der Prod-QA-Client-Patch: ein P1-Crash-Fix für #/two-pager, Ctrl+K auf Nicht-QWERTY-Layouts, die 390px-Mobil-Welle (docs-assistant-Overflow, Map-Chip-Überlappung, ein 39-Routen-Harness), der Abschluss von CAR-137 (konkrete Fehler, v2empty ×5, Hinweise ×13 + Mode-Seiten) und CAR-140, das überall echte v2-Screenshots landet.

Behoben

  • two-pager TDZ (CAR-170, P1, #554): Cannot access 'previewTimer' before initialization — der gespeicherte-Tags-Editor feuerte onChange bereits während der Konstruktion für jeden wiederhergestellten Chip, während die Konstruktionsschleife lexikalisch über let previewTimer saß; dadurch stürzte das komplette #/two-pager-Rendering ab (kein h1, ×19 Sprachen). Scheduler + Binding liegen jetzt über der Schleife; ein verhaltensbasierter Test führt das echte View-Modul aus — vor dem Fix der exakte Prod-Fehler, danach eine gerenderte Seite — plus ein Drift-Gate für die lexikalische Ordnung.
  • Ctrl+K auf Nicht-QWERTY-Layouts (CAR-172, #554): beide Chord-Handler prüften nur e.key — auf einem russischen Layout kommt der Chord als key='л' code='KeyK' an und tat nichts. Jetzt wird auf e.code === 'KeyK' geprüft, in nav-v2.js und app.js; in einem echten Browser mit einem synthetischen ‘л’/KeyK-Chord reproduziert. Der CAR-122-Vertrag wird neu gefasst (siehe Hinweise).
  • docs-assistant 390px-Overflow (CAR-172, #554): die CAR-136-Starter-Chips waren .btn (nowrap, flex-shrink: 0) — ein unumbrechbares 418px-Element schob #/docs-assistant 56px über einen 390px-Viewport hinaus; das CAR-146-Shrink-Muster (in v2-llm.css, die 800-LOC-CSS-Gates unberührt) bringt es auf 0.
  • Map-Chip-Überlappung @390 (#552): auf einem 390px-Viewport überlappten die Map-Meta-Chips die CTA-Zeile (map.css).
  • CAR-137 — konkrete Fehler + v2empty ×5 (#550): fünf generische Fehler-Fallbacks (‘Error’ / ‘failed’) wurden zu konkreten, umsetzbaren Schlüsseln — Evaluate-POST-Fehler, Auto-Pipeline-Stream ohne Terminal-Ereignis, scan→pipeline-Hinzufügen, Repost-Cluster-Laden, Pipeline-Undo; die letzten fünf flachen Leerzustände (#/reports, #/usage, #/portals, #/activity, #/dashboard) schließen sich dem CAR-124-v2empty-Muster an (Erklärung + getaggtes aria-hidden-Beispiel + vorverdrahtete Aktion; 15 neue v2empty.*-Schlüssel, vier tote Einzeilen-Schlüssel entfernt) — alles ×19 Dictionaries, Snapshot neu erzeugt.
  • CAR-137 — HelpHint ×13 + Mode-Seiten-Kit (#550): der kontextuelle «?»-Hinweis sitzt jetzt auf jedem verbleibenden Seiten-H1 (pipeline, reports, dashboard, cv, portals, usage, activity, assessments, map, health, docs-assistant, settings) und über das Kit auf den 8 Mode-Seiten (jede MODES-cfg trägt einen hintKey, gerendert über HelpHint.title).

Hinzugefügt

  • Mobile-390-Harness (#552): ein Playwright-Sweep über jede SPA-Route (31 kanonische + 8 Mode-Seiten = 39 Hashes) bei 390×844 mit einem eingesäten Korpus — pro Route eine horizontale Overflow-Prüfung (scrollWidth gegen clientWidth, 1px Toleranz, benennt den breitesten Übeltäter) plus eine CTA-Treffer-Prüfung (keine Sticky-Leiste/kein Drawer/kein FAB verdeckt eine primäre CTA); opt-in, graceful Skip ohne Browser-Binary, netzfrei.
  • Frische v2-Captures ×48 (CAR-140 Phase A, #551): echte v2-UI-Screenshots aus einem eingesäten CI-isolierten Fixture — dashboard ×19 + job-map ×19 (job-map-ta erster Auftritt, job-map-vi neu) + scan/pipeline/tracker/reports × en/ru — füttern README, Hilfe und das Landing.
  • cvstart.org echte Screenshots (CAR-140 Phase B, #553): die CAR-140-Platzhalter-Slots sind verschwunden — das Landing zeigt die tatsächlichen v2-Captures (Job-Map-Showcase + Screenshot-Zeilen, ×19 Landing-Sprachen).
  • CAR-137-Hinweise (#550): 21 neue übersetzte Schlüssel ×19 (help.hint.* ×20 + die Mode-Seiten-hintKeys) — jede Seite erklärt sich jetzt an Ort und Stelle.

Hinweise

  • Ctrl+K-Vertrag (CAR-122): der Chord öffnet die Befehlspalette — er fokussiert NICHT direkt die Suchbox; der Fokus auf die Suche kommt aus der Palette. Die Zeile «Ctrl+K фокусит поиск» aus der v1.261.0-QA-Checkliste ist damit überholt; der v1.261.1-QA-Prompt trägt die aktualisierte Prüfung.
  • CodeQL echte Fixes (#547): 4 Alerts geschlossen (content.mjs Literal-Key-Iteration strukturell gemacht, Lint-Sweep) — nach dem Release auf v1.261.0 main gelandet, noch vor diesem Patch; der Vollständigkeit halber hier gelistet.
  • Tests 6582 (+51); Browser-Suite 171–172 pass / 0 fail / 1 opt-in Skip; der Mobile-390-Harness läuft eigenständig (node tests/playwright-mobile-390.mjs). Keine Scanner-Quellen angefasst (Registry 121 = 116 EN + 5 RU · 116 Adapter).

[1.261.0] — 2026-10-28

Die Full-Review-Welle ist abgeschlossen (alle HIGH- und MEDIUM-Funde gelandet), der vom Owner gemeldete Sprachwechsel-Fix, Fixes zur Auswertungsqualität, das Hilfe-×18-Fan-out, das cvstart.org-Landing v2 — dazu 4 SDD/OpenSpec-Specs, die die Welle dokumentieren. Jeder Fix landete über einen Rot→Grün-Fix-Forward und ein GLM-5.3-Flash-Review mit frischem Kontext.

Sicherheit

  • FULL-R1 — CSRF-acting-GET-Gate + gesperrte atomare Pipeline-Schreibvorgänge (#519): Sec-Fetch-Site/Origin/Referer-Gate auf /api/stream/*, /api/run/*, /api/geocode (exportiertes ACTING_GET, statisches Coverage-Gate); jeder Read-Modify-Write-Zugriff auf data/pipeline.md / data/last-scan.json unter withFileLock + dem neuen atomicWrite (Temp-Datei im selben Verzeichnis → Rename → Unlink bei Fehlschlag).
  • FULL-R2 — SSRF-Cluster in den Quellen (#514): rss.mjs mit https + Private-Reject; ~25 rohe fetchImpl-Quellen → abgesicherte Transports; Mirrors festgenagelt; Redirect-Validierung für habr/hh/geekjob/getmatch; gemeinsames delay(ms, signal).
  • FULL-R4 — Prosa-Korruption in stripDangerousMarkdown (#513/#518): Schema-Strips nur in Link-/Attribut-Kontexten; Entities werden erst in einer Kopie dekodiert, die nur der Erkennung dient («JavaScript: React, Node» und «R&D» überleben).
  • FULL-M2 — Transport-Härtung (#520): safeGet honoriert timeoutMs mit dem Signal des Aufrufers (Bridge-Controller); guardResolvedHost fällt bei einem DNS-Fehler CLOSED. #525 ergänzt das Entfernen von Credential-Headern bei Cross-Origin-Redirects, das Abkoppeln des Transport-Listeners auf jedem Settle-Pfad und einen Crash-Fix für vorab abgebrochene Signale.
  • FULL-M4 — Logo/Batch (#523): der Logo-Code nagelt die Magic Bytes auf JEDEM Pfad fest (ein falsch deklariertes image/png kann kein SVG tragen), klemmt den Content-Type beim Speichern auf image/*, privater Cache + nosniff; Batch: --parallel auf 1–8 begrenzt, --min-score validiert, BATCH_BUSY als single-flight, llmRateLimit auf Config-/Batch-Mutationen.

Hinzugefügt

  • CAR-147 — sprachabhängiges Auswertungs-Zeitlimit (#524): evalTimeoutMs(lang) — ta/hi bekommen 480 s statt 300 s (indische Schriften tokenisieren mehrere Tokens pro Silbe; die alte Wand erzeugte 502 + einen leeren Report); der Remote-QA-Client wartet 540 s.
  • CAR-133 — cvstart.org-Landing v2 (#532): Parallax-Hero hinter einem reduced-motion-Gate, eine klar als SIMULIERT gekennzeichnete Demo des scan→evaluate→tracker-Flows, Scroll-Reveal-Sektionen mit live verifizierten Zählern, Platzhalter-Slots für die CAR-140-Screenshots.
  • CAR-135 — Hilfe für die UI v2 neu geschrieben, ×18-Fan-out komplett (#533, #540, #541, #542): alle 19 Hilfe-Dateien beschreiben die v2-Shell (einklappbare Nav, Cmd/Ctrl+K-Palette, Skeletons, Beispiel+Aktion-Leerzustände, Scan-v2-Chrome, gruppierte Pipeline mit Undo, Reports v2, Kanban); die UI-Beschriftungen zitieren ihre i18n-Schlüssel; der Satz zu den 121 Quellen wird aus der Registry erzeugt.
  • Specs (SDD/OpenSpec) (#535): Backfill der Wave-two vom 27.10. + drei vorausschauende Specs (Hilfe-Fan-out, Write-Hand-offs, Sprachwechsel-Invarianten).

Behoben

  • Der Sprachwechsel leert #/scan nicht mehr (#534) — vom Owner gemeldet: der view-lokale Scan-Zustand (Ergebnisse, Facet-Chips) liegt jetzt auf Modulebene; ein verhaltensbasierter Playwright-Harness mit um 4 s verzögertem Re-Fetch (rot auf der alten Form).
  • CAR-148/149 — RU-Reports «fehlender Block G» (#530): der Prompt lehrte drei inkonsistente A–G-Zuordnungen; Skeleton + Liste + Beispiel stimmen jetzt mit oferta.md überein (G = Posting Legitimacy); verhaltensbasiertes Drift-Gate.
  • CAR-150 — Pipeline-Undo behält Comp-Metadaten (#537): DELETE antwortet mit comp, POST akzeptiert ein optionales comp hinter einem Gate, die View trägt {token, comp} durch alle Fallback-Zweige.
  • FULL-M3 — tote Quellen melden ehrliche Boards (#522): getro/mycareersfuture/meituan/mokahr/glints werfen bei einer malformed page-1 (eine tote API liest sich nicht mehr als «gesund, 0 Jobs»); pinnedOverride nagelt die company.api-Overrides von 18 Adaptern fest.
  • FULL-M5 — eine einzige Provider-Kaskade (#521): routes/llm.mjs läuft über runActiveProvider (+cachePrefix, Signal); Abfangen im Gemini-Subprozess; Antwortverträge byte-identisch.
  • FULL-M1 — Schreibvorgänge auf gemeinsamen Dateien gesperrt (#526, #539): runTrackedScript + das TRACKER_MUTATING-Roster; outcome/followup-Spawns halten die Sperre; tracker.mjs schreibt via atomicWrite; PUT speichert gesperrt+atomar.
  • FULL-M6 — Server- + Client-Konsolidierung (#531, #536, #525): dotenv mit Null-Prototyp + __proto__-Verweigerung; isPrivateOrLoopback deckt NAT64/6to4/Benchmark/reservierte Bereiche ab; env-config-mtime-Cache; echter Slot-GC im file-lock; safeGet timeout+signal; DNS-Guard fail-closed; SSE ×4 → API.postStream; Fokus-/Label-/Status-Libs; Clipboard wird abgewartet; Hired-Tönung im Dashboard.
  • R3 — CSS-Token-Drift (#527): --accent aufgelöst (die Map-Fokusringe waren still tot); 11 token-fremde Dauern eingefaltet; Drift-Gate.
  • R4 — Nachzügler beim Laden (#538): assessments/mode-page/Pipeline-Preview rendern die CAR-112-Skeletons.
  • CodeQL- + CI-Batch (#517, Fix #539): ungenutzte Imports, das ACTING_GET-Gate importiert die echte Regex, der Lifecycle-Slice neu verankert.

Hinweise

  • Bewusst nicht getan: DNS-Pinning zur Verbindungszeit (braucht undici — liegt außerhalb der Abhängigkeiten, dokumentiertes Residuum); die CAR-140-Screenshots (brauchen die ausgelieferte v2-UI); CAR-137/138/141 (nächster Docs-Durchlauf); die js/missing-rate-limiting-CodeQL-Klasse ist ein dokumentierter False Positive (der eigene Limiter wird nicht angerechnet).
  • Hilfe-×18-Fan-out: die es/de-Wave-1 ließ die Intro-Notiz und das Active-Companies-Karten-Delta aus (de landete sein eigenes Intro; es bekommt ein Einzeilen-Follow-up).

[1.260.0] — 2026-10-26

Die Review-Härtungswelle, acht Merges (#491–#498) aus den opus-5-5- und AI-Review-Runden über die v1.259.0-Flotte: Gehaltsnormalisierung, Report-Datums-Scoping, Geocode-Robustheit, Bundle-Cache-Busting r2+r3, der Deep-Overflow-Fix — dazu zwei UI-v2s (Pipeline, Reports). Jeder Fix landete über einen Rot→Grün-Fix-Forward.

Behoben

  • Gehaltsvergleich-Normalisierung (CAR-143 rev-2): Periodenmarker werden nur nahe der Zahl erkannt, zu der sie gehören — «6 month contract, $120k» annualisiert nicht mehr ×12, und rein angehängte RU/ES-Periodenformen («за месяц» direkt neben der Zahl) schlagen beiläufige Wörter; die $/¥-Symbolfamilie wird erkannt, aber nicht zugeordnet, außer ein expliziter ISO-Code steht in derselben Zeile (AUD/CA/SG-Dollar werden nicht mehr als USD verrechnet, eine ¥-RMB-Form bekommt einen expliziten Vorbehalt statt einer ~20×-daneben-JPY-Umrechnung); nackte 19xx/20xx-Zahlen sind immer Jahre; Bereichszahlen erben die Periode des Partners; minimum und target_range aus dem Profil werden nie zu einem einzigen Bereich zusammengefügt.
  • fixReportDate-Scoping (CAR-144 rev-2): die serverseitig festgenagelte Datumskorrektur greift nur in der Präambel vor der ersten ## -Überschrift (ein Report mit H2-Titel bekommt ein konservatives No-op — ein veraltetes Datum ist akzeptabel, ein erfundenes nicht); innerhalb der Präambel: ein eindeutiger Kandidat wird korrigiert, sonst ein eindeutig fett gesetztes **Date:**, sonst nichts (zwei fette oder zwei schlichte Kandidaten werden nicht umgeschrieben). Das FIX-5-PDF-Label-Gate liest jetzt das real assemblierte Wörterbuch — eine fehlende Locale wirft einen Fehler, statt stillschweigend mit einem englischen Fallback zu bestehen.
  • Habr-Location-Chip + Geocode-Robustheit (CAR-142 rev-2): ein Habr-Meta-Chip wird nur mit strukturellem Beleg zur Stadt (ein Städtefilter-Link oder ein Location-Icon) — Umzugshinweise («Возможна релокация») und Beschäftigungsarten geben sich nie als Orte aus; der Geocode-Cache überlebt jetzt einen Neustart (Flush bei beforeExit/exit/SIGTERM+SIGINT mit Re-Raise, das Dirty-Flag wird erst gelöscht, nachdem der Schreibvorgang gelandet ist), das Herunterfahren ist begrenzt (Exit-Loop-Latch, Generationszähler, Recency-LRU), und ein aufgebrauchtes Geocode-Budget antwortet mit 503 + Retry-After statt eines generischen 502.
  • Bundle-Cache-Busting (CAR-145 r2+r3): die Shell referenziert /js/bundle.js?v=<content-hash> — immutable bei Treffer, no-store bei Abweichung — und eliminiert damit das 5-Minuten-Deploy-Fenster, in dem eine frische Shell auf ein gecachtes, altes Bundle traf. Hash und Stream teilen sich einen Datei-Deskriptor (keine zerrissenen Lesezugriffe); ein kurzer Lesezugriff antwortet mit null statt mit einem Stat-Fallback-Hash, der ein ganzes Deploy vergiften könnte; make-bundle schreibt das Identity-Bundle und die .br/.gz-Begleiter über ein gepunktetes Temp-File + Rename, sodass ein abgebrochener Build weder halb geschriebene Bytes ausliefern noch sein Temp-File hinterlassen kann.
  • Deep-Overflow (CAR-146): ein gespeichertes Research-Briefing, dessen Dateiname allein einen Telefon-Viewport sprengt, kann #/deep nicht mehr über 390px hinausschieben — die Karte wird an ihrer Zeile begrenzt, der Titel bricht um, das Datum bleibt einzeilig; der Narrow-Viewport-Sweep geht #/deep jetzt mit einem überlangen Seeded-Fixture ab (der einzige Fund beider Remote-QA-Läufe, geschlossen).
  • Pipeline-v2-Härtung (CAR-116-Review): Löschvorgänge bestätigen und lassen sich rückgängig machen (mit ehrlichem Undo-Text), keine Host-Company-Fabrikation in den Karten, FNV-1a-Zeilen-IDs, echte Bulk-Zählungen und ein Re-Entrancy-Guard auf Bulk-Operationen.

Hinzugefügt

  • Pipeline v2 (CAR-116): angereicherte Karten, eine gruppierte Ansicht und Bulk-Discard mit Undo; 17 neue pipe.*-Schlüssel kamen in allen 19 Wörterbüchern übersetzt aus.
  • Reports v2 (CAR-118): Live-Suche mit Filtern nach Score-Band/Legitimacy/Firma/Datum, sortierbare Kopfzeilen (aria-sort), eine persistente Kartenansicht mit Aktionsschaltflächen je Band, ein Klick-zum-Filtern-Score-Histogramm und das vereinheitlichte «Company — Role» / «x.x/5»-Rendering (window.ReportOps); 31 neue rep2.*-Schlüssel kamen in allen 19 Wörterbüchern übersetzt aus.

Hinweise

  • Jeder Fix kam durch eine Review-Runde mit Rot→Grün-Nachweisen; die beiden AI-Review-HIGH-Funde am ersten Bundle-r2 (Short-Read-Hash, Companion-Atomicität) schließt r3, und die CAR-143/CAR-144/CAR-142-Runden prüften jeweils die offenen Funde ihrer Vorgänger nach.
  • Bewusst nicht getan: die Map-Cluster-Ansicht bleibt CAR-125 (in der Warteschlange); die serverseitige Wiederherstellung von Pipeline-Metadaten ist ein eigenes Ticket; keine rückwirkenden Fixes für Inhalte, die unter den v1.259.0-Zuständen vor rev-2 gespeichert wurden.
  • Tests 5988 (+165); Browser-Suite 152 bestanden / 0 fehlgeschlagen / 1 Opt-in-Skip. Keine Scanner-Quellen angefasst (Registry 121 = 116 EN + 5 RU · 116 Adapter); die 48 neuen i18n-Schlüssel landeten mit ihrem ×19-Fan-out innerhalb der Feature-PRs selbst.

[1.259.0] — 2026-10-25

Die zweite Welle der Agenten-Flotte, sechs Fixes: Report-Daten sind serverseitig festgenagelt, der Map-Geocoder cacht und liest RU-Städte, die Hilfe ×18 zitiert lokalisierte Schaltflächenbeschriftungen, UI-Sätze mischen keine Sprachen mehr, Gehaltsvergleiche werden serverseitig berechnet — und das JS-Bundle kommt vorkomprimiert aus (Kaltstart 3.1 MB → 598 KB).

Behoben

  • Erfundene Report-Daten (CAR-101): der Auswertungs-Prompt nagelt das heutige Datum jetzt serverseitig fest («das Date:-Feld MUSS exakt sein — wortgetreu übernehmen; niemals erfinden»), und fixReportDate schreibt ein abgedriftetes Datum an jeder Übernahmestelle auf heute zurück (Anthropic-Zweig, Gemini-Subprozess, OpenAI-kompatibler Schwanz, /api/deep, Auto-Pipeline) — mit Warnung + Aktivitätseintrag; eine Korrektur, nie eine Zurückweisung. 349/789 Prod-Reports trugen erfundene Daten; neue können es nicht mehr.
  • Map-Geocoding (CAR-105): die kyrillischen Stadt-Zeichenketten aus hh.ru/Habr-Zeilen erreichen jetzt den Geocoder; ein persistenter, begrenzter Cache (data/geocode-cache.json, withFileLock) sorgt dafür, dass eine aufgelöste Stadt den Provider nie zweimal trifft; Geocode-Aufrufe sind pro Anfrage budgetiert, sodass sich die Map fortschreitend füllt, statt 13.9 s zu blockieren.
  • Gemischtsprachige UI (CAR-108): 23 Leaks über Schlüssel hinweg in 17 von 19 Wörterbüchern behoben (85 Werte) — «все matching», «только remote», «Открыть Scan», der Funnel «Evaluated → Applied…» und mehr wurden zu vollständig lokalisierten Sätzen, die das eigene Produktvokabular der jeweiligen Sprache wiederverwenden. i18n-no-latin-leaks um die Fragment-Tabelle + Funnel-Probe erweitert (rot→grün).
  • Währungs-Urteils-Kippung (CAR-109): der Gehaltsvergleich wird serverseitig in comp-compare.mjs berechnet und kanonisch eingebettet (Candidate minimum: … per YEAR (raw: …) vs. JD offer: …); Monatsbeträge ×12, k/к/тыс/萬 und Dezimalkomma-Formen werden vor dem Vergleich normalisiert; eine unsichere Umrechnung kann allein das Urteil nie kippen (der zh-TW-Fall «€80–100k ниже минимума» ist tot). Das Modell multipliziert nie.
  • Hilfe ×18 Schaltflächenbeschriftungen (CAR-107): die lokalisierten Hilfe-Bundles zitierten englische Beschriftungen («⚡ Run live», «Save», «Scan now»), die die UI nicht mehr zeigt — 263 Ersetzungen über 18 Sprachen, aus den View-Quellen abgeleitet; der Docs-Assistent erbt den Fix.

Hinzugefügt

  • Vorkomprimiertes Bundle + cachebarer Kaltstart (CAR-104): make-bundle.mjs erzeugt bundle.js.br (Brotli q11) + .gz zum Release-Zeitpunkt; eine Bundle-scoped-Middleware verhandelt br > gz mit Vary: Accept-Encoding, public, max-age=300, must-revalidate + ETag/304; frischegesichert (ein Begleiter liefert nie etwas Älteres als das Identitäts-Bundle), direkte Artifact-Abfragen antworten 404, CSP byte-identisch. Kaltstart: 3.1 MB → ~0.6 MB über die Leitung (−80%); wiederholte Besuche innerhalb von 5 Min übertragen ≈0 Bytes.

Hinweise

  • Alle Fixes stammen aus der Agenten-Flotte mit Rot→Grün-Nachweisen (13 + 28 + 1 + 30 + 7 neue Fälle über ihre Suiten) und wurden in Review-Runden nachgeschärft (CodeQL #579/#580/#584 im Code behoben — Stub-URLs über new URL().host geparst, eine tote Prompt-Zeichenkette gestrichen).
  • Die v1.258.0 Score-Backfill-Zahlen sind jetzt in CAR-129 vermerkt (updated: 22, reportScoreless: 159).
  • Bewusst nicht getan: keine rückwirkende Datenkorrektur für die 349 historischen Reports (ein Backfill wäre Owner-freigegebener Betrieb), keine Map-Cluster-Ansicht (CAR-125 bleibt hinter diesem Geocode-Fix in der Warteschlange).
  • Tests 5823 (+74). Keine Scanner-Quellen angefasst (Registry 121 = 116 EN + 5 RU · 116 Adapter); keine i18n-Schlüssel (CAR-108 ändert nur die Werte bestehender Schlüssel).

[1.258.0] — 2026-10-25

Sechs Fixes aus der Agenten-Flotte in einem Zug: der #/scan-Zähler mischt keine Universen mehr, Deep Research verlangt Quellen, Formularfehler lassen das Feld aufleuchten, Ladezustände bekommen Skeletons und ein sofortiges h1, und Auswertungen cachen ihr 37k-Token-Prompt-Präfix.

Behoben

  • #/scan-Zähler «Aktive Unternehmen» (CAR-100): der Zähler erfasste unterschiedliche Firmen über ALLE Ergebniszeilen hinweg (1554 auf Prod — allein hh.ru steuert Hunderte bei), während der Nenner die API-basierten verfolgten Unternehmen zählte (~90) — zwei Universen in einem Bruch. Variante (a): der Zähler erfasst jetzt Firmen unter den Zeilen, die der API-basierte verfolgte Scan selbst geholt hat (abgeglichen über _entry ?? company; hh.ru/telegram-Arbeitgeberzeilen fallen heraus); der Pre-Scan-Fallback wanderte in dasselbe Universum (er konnte «104/90» anzeigen).
  • Deep-Research-Fabrikation (CAR-110): der Deep-Prompt trägt jetzt einen harten Vertrag — jede faktische Behauptung endet mit [source: domain.com] (nicht benennbar → nicht behaupten; ein erfundener Marker ist schlimmer als ein geschriebenes «unknown»), unbekannte Fakten werden als unknown notiert, und der Report MUSS mit einer ## Data freshness-Sektion enden. Frische-Anker: das heutige UTC-Datum + eine optionale Firmen-url auf POST /api/deep (begrenzt, serverseitig nie abgerufen).
  • Formularfehler heben das Feld hervor (CAR-130): ein fehlgeschlagener POST markiert das erste Formularfeld mit aria-invalid + .is-error und fokussiert es (WCAG 3.3.1); beim Bearbeiten wird die Markierung zurückgesetzt. Der Netzwerkfehler-Hinweis ist Deployment-bewusst — Loopback behält den Dev-Befehls-Hinweis, eine ausgelieferte Origin bekommt «Der Server antwortet nicht» statt des bash web-ui/bin/start.md-Rats (das Verbindungs-Banner hatte denselben Hardcode).
  • Ladezustände (CAR-112): #/map und #/tracker rendern ihr h1 sofort (das Router-Fokus-Ziel existierte erst, nachdem die Daten angekommen waren), und ein gemeinsamer Skeleton-Helfer (Skeleton.rows, aria-hidden-Schimmerzeilen innerhalb einer role="status"-Region, die common.loading wiederverwendet) ersetzt den nackten Text «Wird geladen…» auf Tracker, Scan-Ergebnissen und der Map-Hülle; prefers-reduced-motion stoppt den Puls.
  • Prompt-Caching für Auswertungen (CAR-111): buildEvaluationPromptParts teilt den ~37k-Token-Prompt in ein byte-stabiles Präfix (CV + Profil + Mode-Dateien + Anweisungen) und den JD-Schwanz; der Anthropic-Pfad sendet [prefix + cache_control: ephemeral] + [JD] — das Präfix wird bei jedem Aufruf nach dem ersten zum Cache-Lese-Tarif abgerechnet (≈10× günstiger). Ein fehlendes oder nicht übereinstimmendes Präfix fällt offen auf die byte-identische alte Anfrage zurück; die OpenAI-kompatible Kaskade bleibt unangetastet (serverseitiges Caching dort).

Hinweise

  • Alle sechs Fixes stammen aus der Agenten-Flotte, mit Rot→Grün-Nachweisen (5 + 7 + 7 + 7 + 8 neue Fälle) und Review-Runden; die ersten CAR-111-CodeQL-Alerts (#579/#580) wurden im Code behoben — der Test-Stub parst den URL-Host, statt Teilzeichenketten zu vergleichen, und eine tote Full-Prompt-Zeichenkette wurde gestrichen.
  • Der Score-Backfill lief auf Prod (v1.256.0-Endpunkt, vom Owner freigegeben): updated: 22, missingReport: 0, reportScoreless: 159 — 159 unbenotete Zeilen zeigen auf Reports, deren Header dem Maschinenblock vorausgehen oder unparsebare Score-Formate tragen; wiederherstellbar nur durch Neuauswertung oder einen breiteren Parser-Durchlauf (in CAR-129 vermerkt).
  • Bewusst nicht getan: keine Nullen-zuletzt-Änderung an der Commute-Spalte (vorbestehender Infinity-bei-absteigend-Quirk), keine rückwirkende Neubepreisung alter Nutzungsdatensätze, keine .is-error-artige Hervorhebung für die Scan-Filterformulare (CAR-130 auf den gemeinsamen Mode-Page-Submit-Helfer + den api.js-Hinweis beschränkt).
  • Tests 5749 (+36). Keine Scanner-Quellen angefasst (Registry 121 = 116 EN + 5 RU · 116 Adapter); keine i18n-Schlüssel (der CAR-130-Hinweis nutzt conn.down wieder; die Skeleton-Region nutzt common.loading wieder).

[1.257.0] — 2026-10-25

Zwei Fixes aus der Agenten-Flotte: der Hilfe-Assistent in der App versteht Devanagari und Tamil, und die Nutzungsseite zeigt, was Hermes tatsächlich kostet.

Behoben

  • Abruf des Hilfe-Assistenten für hi/ta (CAR-103): die Wortklasse des Keyword-Tokenizers des Docs-Assistenten war [\p{L}\p{N}\u30fc]+ — keine kombinierenden Zeichen. Jede Devanagari-Matra (ा ै ्…) und jedes tamilische Vokalzeichen (ே ை ்…) zerschnitt ein Wort in Fragmente; die Längenregel warf kurze Fragmente weg (eine Hindi-Anfrage matchte 0 Abschnitte), und längere Wörter wurden zu Müll enthauptet, der mit zusammenhangslosen Abschnitten kollidierte. Die Klasse behält jetzt \p{M}; der CJK-Bigram-Pfad bleibt unangetastet. hi «मैं स्कैन कैसे चलाऊं?» und ta «ஸ்கேன் எப்படி இயக்குவது?» holen die richtigen Abschnitte aus den ausgelieferten Bundles.
  • Nutzungskosten für Hermes (CAR-106): normalizeUsage() presste die Provider-Nutzung auf {in, out} zusammen und warf den vom Gateway gemeldeten cost-Wert stillschweigend weg — #/usage zeigte $0.0000 über 9.5 M Hermes-Tokens (seine Preistabellen-Zeile ist 0/0). Die Form des Nutzungseintrags erhält ein optionales, abwärtskompatibles cost?; der Aggregator bevorzugt den vom Provider gemeldeten Kostenwert je Eintrag und greift nur bei Fehlen auf die Preistabellen-Schätzung zurück; fehlerhafte und negative Werte werden verworfen, nie erfunden.

Hinweise

  • Beide Fixes stammen aus der Agenten-Flotte mit Rot→Grün-Nachweisen (3 + 5 neue Fälle; 14/14 und 10/10 grün; Nachbarn 78/78 und 61/61). Die ersten PRs (#470/#471) trugen eine veraltete Worktree-Basis, die mit dem Squash-Merge von v1.256.0 kollidierte — ersetzt durch saubere Cherry-Picks (#472/#473).
  • Bewusst nicht getan: keine rückwirkende Neubepreisung historischer data/llm-usage.jsonl-Zeilen (sie tragen kein Kostenfeld; nur neue Einträge profitieren).
  • Tests 5713 (+8: docs-assistant ×3, usage ×5). Keine Scanner-Quellen angefasst (Registry 121 = 116 EN + 5 RU · 116 Adapter); keine i18n-Schlüssel.

[1.256.0] — 2026-10-25

Tracker-Datenqualität: die Rolle wird nie als Firma abgelegt, ein Job-Board nie als Arbeitgeber, unbenotete Zeilen tauchen nicht mehr zuerst auf — und ein One-Shot-Endpunkt füllt fehlende Scores direkt aus den Reports selbst nach.

Hinzugefügt

  • Score-Backfill (CAR-129): POST /api/tracker/backfill-scores füllt die Score-Zelle von Zeilen nach, deren verknüpfter Report einen auswertbaren Score trägt (181 evaluierte Zeilen hatten einen Report, aber keinen Score). Bereits benotete Zeilen, explizite Sentinels (N/A), Zeilen ohne Report und Reports ohne Score werden nie angefasst; nur die Score-Zelle wird neu geschrieben, unter der Datei-Sperre; die Score-Form wird an der Schreibstelle validiert und auf die X.X/5-Konvention des Trackers normalisiert; der Lauf ist idempotent und liefert {ok, updated, missingReport, reportScoreless} zurück.

Behoben

  • Die Rolle ist nie die Firma (CAR-128): guessCompanyRole behandelte die LINKE Seite einer Bindestrich-Header-Zeile als die Firma, aber Boards schreiben beide Reihenfolgen — «Senior Frontend Engineer - Grafana Labs» legte die Rolle ALS die Firma ab (13 Zeilen: Grafana, CircleCI…). Eine Heuristik mit Wortgrenzen um Rollen-Keywords wählt jetzt die Rollenseite, und ein Beschäftigungstyp wird nie zum Arbeitgeber («Senior Engineer - Remote (EU)» legt nichts ab statt «Remote (EU)»).
  • Ein Job-Board ist nie der Arbeitgeber (CAR-127): der Domain-Slug-Fallback legte hh.ru-Zeilen als «hh» ab (120 Zeilen). Die Slugs hh/habr stoßen zur Kein-Arbeitgeber-Liste; die Employer-Inferenz mitten im Satz («в компании X», «X ищет») läuft jetzt auch für Job-Board-Hosts (hh.ru/kz/uz/by, habr.com) — wo der Seitentext den echten Arbeitgeber nennt. Nebenbei fand sich die Wurzel: das ASCII-\b/\w in diesen Inferenz-Mustern hat auf Kyrillisch nie gematcht — still tot seit v1.248.4; Unicode-Lookbehinds und \p{L}-Klassen ersetzen sie.
  • Unbenotete Zeilen sortieren zuletzt (CAR-129): die Score-Sortierung des Trackers nutzte ein -1-Sentinel, sodass bei der standardmäßigen aufsteigenden Sortierung jede unbenotete Zeile vor jeder benoteten auftauchte. Nullen sortieren jetzt in beide Richtungen zuletzt (der Score-FILTER behält sein -1 — „unbenotet fällt durch einen ≥4-Filter“ ist dort die korrekte Semantik).

Hinweise

  • Historische Zeilen werden von diesem Release NICHT migriert: die Parser-Fixes greifen bei neuen Auswertungen; Scores sind über den Backfill-Endpunkt wiederherstellbar, während die 120 «hh»-Arbeitgeber-Zellen eine Neuauswertung brauchen, kein Umschreiben.
  • Eine Opus-5-5-Review-Runde ist eingearbeitet: das nicht verankerte «X ищет»-Muster wurde vor dem Ausliefern gestrichen (jede großgeschriebene Folge vor dem Verb wäre als Arbeitgeber abgelegt worden — die No-Fabrication-Invariante), satzanfängliche «В…»-Anker kamen hinzu, und der Backfill-Writer prüft die Zielzelle erneut (doppelte #-Zeilen existieren nach manuellen Bearbeitungen), erhält die Spaltenanzahl einer handverformten kurzen Zeile und stoppt an der ersten Zeile außerhalb der Tabelle. Der Punkt in einem punktierten Namen («Сбер. IT») ist für den «в компании»-Anker vom Satzpunkt nicht zu unterscheiden — der konservative Präfix («Сбер») wird abgelegt; das verb-verankerte Muster fängt die volle Form.
  • Bewusst nicht getan: keine Comparator-Extraktion aus tracker.js in eine unit-testbare Lib (das source-statische Gate bleibt; in CAR-129 als Follow-up vermerkt), keine Nullen-zuletzt-Änderung an der Commute-Spalte (vorbestehender Infinity-bei-absteigend-Quirk), keine Datenmigration für die «hh»-Zeilen.
  • Tests 5705 (+10: 5 Identitätsfälle in auto-pipeline-jd-gate, 2 CAR-128, das CAR-129-Sortier-Gate, 4 Backfill inkl. des Hostile-Path-Pins — abzüglich der ersetzten v1.248.x-Fälle). Keine Scanner-Quellen angefasst (Registry 121 = 116 EN + 5 RU · 116 Adapter); keine i18n-Schlüssel.

[1.255.2] — 2026-10-24

Drei für Nutzer sichtbare Fixes aus der Live-Regression und einem Prod-Crash-Report: der #/scan-Render-Crash, die blinde Vietnamese-Sprachprüfung und der wiederkehrende Verlust des Summary-Blocks in zh-TW.

Behoben

  • #/scan-Crash (CAR-99): die Count-Gate-Regenerierung seit v1.253.0 schrieb das FALLBACK_SOURCES-Literal mit einem doppelten Komma am Ende jedes Eintrags — 120 Elision-Löcher im Array. new Set(FALLBACK_SOURCES.map((s) => s.value)) in der Scan-View hielt daraufhin undefined, und id.length im Firmen-Klassifikator warf bei jedem Seiten-Render TypeError: Cannot read properties of undefined (reading 'length') (auf Prod von logbuf gefangen). Die Löcher sind entfernt, und ein neues Gate (4 Specs, rot-verifiziert) führt die Datei aus und schlägt bei jedem Loch, unbrauchbaren Eintrag oder undefined im Adapter-ID-Set fehl — das rein textuelle Drift-Gate konnte diese Klasse nicht sehen.
  • Blinde vi-Sprachprüfung (CAR-97): Vietnamesisch ist Lateinschrift und hatte keinen Eintrag in der Stoppwort-Tabelle der Live-QA, daher zählten die „vi-Stoppwörter” englische Treffer und eine vietnamesische Antwort las sich als report not in vi (Live-Regression: vi 2, en 2). Vietnamesisch hat jetzt seine eigene Zehn-Wort-Tabelle mit Funktionswörtern — ein rein vietnamesischer Report besteht, ein englischer fällt weiterhin durch.
  • zh-TW verlor den SCORE_SUMMARY-Block (CAR-98): die abschließende Spracherinnerung sagte nur, dass das Maschinenformat nicht übersetzt werden darf, nie aber, dass der Summary-Block existieren muss — ein kurzer zh-TW-Report (5,983 Zeichen) trug die A–G-Blöcke, ließ den Block aber komplett weg (ein Rezidiv der Klasse v1.239.2). Die Eröffnungs-Direktive und die abschließende Erinnerung stellen jetzt klar, dass der Block Pflicht ist und der Report ohne ihn ungültig ist.

Hinweise

  • Diese Version ändert absichtlich keine Scanner-Quelle, keine Registry-Zählung (121 = 116 EN + 5 RU · 116 Adapter) und keine Provider-Verdrahtung — sie ist nur Fixes, die Count-Gates bleiben unangetastet.
  • Tests 5695 (+9: car99-fallback-holes ×4, car97-vi-lang-check ×4, die CAR-98-Prompt-Invariante ×1). Browser 143/143. Der vi/zh-TW-Live-Recheck fährt mit der Post-Deploy-Regression mit.

[1.255.1] — 2026-10-24

Zwei Review-Fix-Runden: das Opus-Review der vietnamesischen Lokalisierung (9 Befunde) und das Second-Pass-Review der CAR-91/92-Fixes (5 Muss-Fixes) — beide mit Rot→Grün-Tests geschlossen.

Behoben

  • Review-Runde der vi-Lokalisierung (CAR-88-Follow-up): das Hangul-Zeichen (신), das sich in project.subtitle / project.roleHint eingeschlichen hatte, ist korrigiert (độ khớp tín hiệu), mit einem Gate, das jedes CJK-/Kana-Zeichen in einem vi-Wert fallen lässt, das das EN-Wörterbuch nicht selbst trägt; die sechs URLs mit Leerzeichen in docs/help/vi.md (what-is career-ops, apply for a job, set up playwright und drei weitere) sind zu den echten Guide-Slugs hypheniert, mit einem kein-Leerzeichen-in-URLs-Gate.
  • Auswertungs-Heading-Grenzen (CAR-92 r2 H1): &, ., /, ' sind jetzt Wortzeichen in der linken Grenze des Block-Buchstabens — ## Q&A, ## Plan B, ## Ph.D. requirement, ## E-commerce registrieren sich nicht länger als Blöcke A/B/D/E; der nackte Zeilenende-Terminator wird nur nach einem Block-Wort-Token akzeptiert (Block/блок/블록/…); ASCII - hat die ausgeschriebenen Terminator-Klassen verlassen, damit E-commerce-/ई-मेल-Headings überleben.
  • Ukrainisch/russisch nummerierte Reports (CAR-92 r2 H2): der А-Б-В-Г-Д-Є-Ж-Sequenz-Detektor ist jetzt ein gemeinsamer Helfer; findet er auf einer Heading-Ebene 3+ Sequenzbuchstaben, wird diese Ebene das Referenz-Level des Cutters — mit Buchstaben versehene ### A.-Untersektionen schneiden den Report nicht mehr an Block Б ab.
  • Lebenszyklus getragener Zeilen (CAR-92 r2 M1): Zeilen, die eine fehlgeschlagene Quelle in den nächsten Scan trägt, werden mit carriedSince gestempelt, nach 30 Tagen oder 5 aufeinanderfolgenden Übertragungen verworfen und hinter den frischen Zeilen angehängt, statt sich still für immer wieder anzusammeln.
  • Gemini-Synthesis-Nenner + Legitimacy (CAR-92 r2 M2) und der Body-Score-Pfad des Subprocess (M3): aus der Befunde-Datei gelesen, mit Rot-Tests behoben.
  • Cold-Load-Bundle-Drift-Gate für das vi-Wörterbuch aktualisiert (90 Script-Tags / 87 bündelbar) und dessen ungenutzte Test-Bindung entfernt (CodeQL 572).

Hinweise

  • Die vom Review angemerkte Adapter-Zähl-Formulierung im „Latest“-Banner der README.vi lebt im Vorherige-Version-Banner und spiegelt das EN-README bereits Byte für Byte — unangetastet gelassen, um die EN↔vi-Parität zu wahren (im Commit-Body dokumentiert).
  • Tests: 5686 (+26: eval-validate-opus-r2, scanner-carryover-r2, vi-Gate-Assertions). Registry unverändert bei 121 Quellen (116 EN + 5 RU) · 116 Adapter.

[1.255.0] — 2026-10-24

Vietnamesisch (Tiếng Việt) kommt als 19. UI-Sprache hinzu — ein 1525-Schlüssel-Wörterbuch in voller Parität mit EN, Erkennung für vi/vi-VN, das vollständige Hilfe-Paket, README- und CHANGELOG-Spiegel, die cvstart.org-Landingpage-Integration und das 🇻🇳 im Sprachumschalter.

Hinzugefügt

  • Vietnamesisch (vi) — 1525/1525 Schlüssel in voller Parität mit en; detect() akzeptiert vi und vi-VN; Vietnamesisch ist LTR (nie in RTL_LANGS). ‘Pipeline’ bleibt ‘Pipeline’ — ein übliches technisches Lehnwort, auf der Whitelist.
  • Vollständiges docs/help/vi.md (33 H2 / 125 H3), dazu die README.vi.md- und CHANGELOG.vi.md-Spiegel und die vietnamesischen Scaffold-Strings in prompts.mjs (LOCALE_NAMES + SCAFFOLD_STRINGS) — vietnamesische LLM-Ausgabe funktioniert ab Werk.
  • cvstart.org-Landingpage auf Vietnamesisch — site/src/i18n/vi.json, der Sitemap-Locale-Eintrag und ein dashboard-vi.png-Screenshot; der Sprachumschalter bekommt 🇻🇳 (19 Positionen).
  • Enumerations-Gates 18 → 19 — LANGS, detect-Sonden, i18n-Audit, Changelog-Parität, README-Übersetzungsblock, Locale-Sweep — plus das Red-First-tests/i18n-vi-locale.test.mjs (139 Zeilen).

Hinweise

  • Die Landingpage bekommt vi — eine bewusste Abweichung vom ta-Präzedenzfall (jenes Release hielt die Landing absichtlich bei 17); dokumentiert in der Release-Spezifikation.
  • vi ist lateinisch geschrieben, daher greift das no-latin-leaks-Gate nicht (es bewacht nicht-lateinische Locales); lateinischer Tech-Wortschatz ist hier die Norm.
  • Testuntergrenze: 5634 → 5642 (1 übersprungen = der Opt-in-Browsertest zum Layout-Capture, unverändert).

[1.254.0] — 2026-10-24

Ein Härtungs-Release aus der Review-Runde mit dem Maximal-Modell: der Scanner-Snapshot verliert nie wieder Zeilen, elf Invarianten-Verstöße der LLM-Schicht sind behoben, dreiundzwanzig SPA-Must-Fixes landen, und die Paylocity-ATS stößt zum Scanner — die Registry liefert jetzt 121 Quellen (115 EN + 5 RU) mit 116 Adaptern.

Hinzugefügt

  • Paylocity-ATS (Parent #5687): Tenant-Boards auf recruiting.paylocity.com, totes Board 302 → JobNotFound auf 404 gemappt, damit die Quarantäne den Eintrag in den Ruhestand schickt, max_jobs-Cap mit Truncation-Flag. Registry: 121 Quellen = 116 EN + 5 RU · 116 Adapter; die Zähl-Gates regeneriert.

Behoben

  • Scanner-Snapshot-Sicherheit (R-12): ein Scan, der nichts versucht, BEHALTET jetzt den Snapshot (nothing scanned); ein Voll-Ersatz überträgt die alten Zeilen der fehlgeschlagenen Quellen — pro Entry gestempelt — erneut durch die AKTUELLEN Filter, landend nur in filtered.
  • Elf Invarianten-Verstöße der LLM-Schicht: die Sprachdirektive öffnet UND schließt die Deep-/Mode-Prompts; der Gemini-Subprocess reicht --lang durch, Nicht-Null-Exit → 502, leckt kein stderr zum Kunden, hält 300 s ein und zeichnet Usage auf; der Manual-Fallback trägt die Posting-URL; Truncation und Bundle-Warnungen tauchen in /api/mode auf; die Spend-Tier ist nicht mehr vom Kunden überschreibbar; ein Client-Disconnect bricht den Provider-Aufruf in flight ab; der Repeat-Heading-Cutter zerstört keine gültigen Reports mehr; Score/Legitimacy-Extraktoren stimmen mit dem Validator überein; die ukrainische Sequenz und das arabische Wa sind straffer.
  • Eine Opus-5-5-Review-Runde ÜBER die Fixes selbst (8 Muss): die Multi-Letter-Registrierung des Cutters, weitere Heading-Terminatoren, die Abort-Verdrahtung des Gemini-Subprocess, die gestempelte Carry-Over-Attribution, getragene Zeilen laufen erneut durch die aktuellen Filter, das Referenz-Heading-Level nach Distinct-Letters.
  • Dreiundzwanzig SPA-Must-Fixes in den Sourcing-Views (der Single-Page-Pager-Append, Pipeline-Zeilen-Tastatur, Saved-Search-Filter-Wiederherstellung, Source-Select-Resets, Config-Default-Rücksetzung, Listener-Leaks, SSE-Close-am-Terminal, Scan-Runner-Teardown, ein nackter Fetch, fehlgeschlagene Ladevorgänge, die leer aussahen, eine globale Kollision, Fokuserhalt) und den Assist-Views (der tote Help-Deep-Link, Help-Listener-Leaks, das Two-Pager-Blank-Overwrite-Neu-Scharfmachen, Single-Flight bezahlter Läufe, stille Stream-Enden, ewige Spinner-Fehlerpfade, Geisterzeilen gescheiterter Filter, Docs-Fab-Duplikate + Sprache).

Hinweise

  • Die ganze Runde wurde von Opus 5-5 mit maximaler Strenge rezensiert — die Ports vor dem Merge (21 Befunde, 13 behoben) und die Fixes selbst post-hoc (8 Muss, alle hier mit Rot→Grün-Tests).
  • Test-Boden: 5262 → 5634 (372 neue Specs über Quellen, Scanner, LLM-Schicht und SPA).

[1.253.1] — 2026-10-24

Zwei HIGH-Sicherheitsfunde aus dem Review mit dem Maximal-Modell sind behoben: IPv6-Literal-URLs umgehen den SSRF-Guard des Scanners nicht mehr, und die Escape-Regex des CV-Markdowns backtracket nicht mehr quadratisch.

Behoben

  • IPv6-Literale umgingen den SSRF-Guard (http-json.mjs): ein geklammertes IPv6-Literal ließ dns.lookup werfen und der Guard fail-open. Jetzt werden die Klammern entfernt und das Literal via isIP klassifiziert — ohne DNS, ohne Fail-open.
  • ReDoS im CV-Markdown-Escape (security.mjs): das Muster backtrackete quadratisch — < + ~100k Leerzeichen kosteten ~16 s; jetzt ~1 ms mit einer flachen begrenzten Klasse. Alles früher Escapete wird weiter escapet.

Hinweise

  • Beide Fixes tragen Rot→Grün-Regressionstests (3 neue IPv6-Fälle + ReDoS mit Zeitgrenze; 5511 Tests, +7).
  • Die Scanner-Quelldateien sind nicht betroffen — der Guard lebt im gemeinsamen Transport.

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