Download index.html from getreadystack/pld-liability-window-lint: direct link, hf CLI and curl.
- Browser
- Download file 48 kB
-
https://huggingface.co/spaces/getreadystack/pld-liability-window-lint/resolve/main/index.html
- Command line
-
hf download hf://spaces/getreadystack/pld-liability-window-lint/index.html
-
curl -L -o index.html https://huggingface.co/spaces/getreadystack/pld-liability-window-lint/resolve/main/index.html
48 kB
| <html lang="en"> | |
| <head> | |
| <meta charset="utf-8"> | |
| <meta name="viewport" content="width=device-width,initial-scale=1"> | |
| <title>EU product Liability 2026 deadline — check your release notes free</title> | |
| <meta name="description" content="Check changelogs and release notes for release dates, support windows, CVE-named security fixes, and AS-IS disclaimers described by the directive."> | |
| <style> | |
| :root{color-scheme:light}body{margin:0;font:15px/1.55 system-ui,-apple-system,"Segoe UI",sans-serif;background:#faf9f5;color:#1a1512} | |
| .wrap{max-width:960px;margin:0 auto;padding:28px 18px 60px}h1{font-size:26px;margin:0 0 6px}.lede{color:#4a403a;margin:0 0 16px} | |
| textarea{width:100%;min-height:260px;font:13px/1.45 ui-monospace,Menlo,Consolas,monospace;padding:12px;border:1px solid #d9d0c4;border-radius:8px;box-sizing:border-box} | |
| .bar{display:flex;gap:10px;align-items:center;margin:12px 0}button{font:600 15px system-ui;padding:10px 18px;border:0;border-radius:8px;background:#1a1512;color:#fff;cursor:pointer} | |
| input[type=date]{font:14px system-ui;padding:8px;border:1px solid #d9d0c4;border-radius:6px} | |
| table{border-collapse:collapse;width:100%;font-size:14px;margin-top:10px}th,td{text-align:left;padding:8px 10px;border-bottom:1px solid #eee;vertical-align:top}th{font-size:12px;letter-spacing:.06em;text-transform:uppercase;color:#7a6e65} | |
| .sev.error{color:#a8551f;font-weight:700}.sev.warn,.sev.warning{color:#96691f}.ok{color:#2a6446;font-weight:600}.sum{font-weight:600} | |
| .note{font-size:13px;color:#7a6e65;margin-top:18px}#paid{margin-top:22px;padding:14px 16px;border:1px solid #e2d8cb;border-radius:10px;background:#fffdfa} | |
| </style> | |
| <script data-grow-initializer="">!(function(){window.growMe||((window.growMe=function(e){window.growMe._.push(e);}),(window.growMe._=[]));var e=document.createElement("script");(e.type="text/javascript"),(e.src="https://faves.grow.me/main.js"),(e.defer=!0),e.setAttribute("data-grow-faves-site-id","U2l0ZTphZjljMzgyMC0yMmU5LTRhYjgtYTIxNS03OTRhMGY1N2ExYzM=");var t=document.getElementsByTagName("script")[0];t.parentNode.insertBefore(e,t);})();</script> | |
| <!--yj-canon-s101--><link rel="canonical" href="https://getreadystack.com/tools/pld-liability-window-lint"></head> | |
| <body> | |
| <div class="wrap"> | |
| <h1>EU product Liability 2026 deadline — check your release notes free</h1> | |
| <p class="lede">Checks CHANGELOG.md and release notes for the four facts the EU Product Liability Directive makes load-bearing on 9 December 2026: release dates, support window, CVE-named security fixes, void AS-IS disclaimers. Runs entirely in your browser — nothing is uploaded.</p> | |
| <textarea id="src" spellcheck="false"># Changelog | |
| All notable changes to Ledgerbridge are recorded here. The project is actively maintained, | |
| and the software is provided AS IS, without warranty of any kind. | |
| ## [Latest] | |
| - Various fixes and improvements | |
| - Tightened the importer | |
| ## 2.4.0 | |
| - Fixed a security issue in the CSV import path | |
| - Bug fixes | |
| ## 2.3.1 - 2024-11-02 | |
| - Patched an XSS in the report viewer | |
| - 2.3.0 was yanked | |
| - Release 3.0.0 is dated 2027-01-10 in the signed manifest | |
| ## 2.2.0 - 2024-06-18 | |
| - Liability for this library follows Directive 85/374/EEC, and integrators accept no liability. | |
| - The new Product Liability Directive applies from 2027-06-01.</textarea> | |
| <div class="bar"><button id="go">Check</button><label>as of <input type="date" id="today"></label></div> | |
| <div id="out" aria-live="polite"></div> | |
| <div id="paid"><strong>Free here:</strong> Lints the open CHANGELOG.md or release-notes file and names every entry that will not carry a liability date, a support window or a CVE reference on 9 December 2026.. <strong>In the editor:</strong> Lints every changelog and release-notes file in the workspace at once and writes out a dated Markdown + CSV evidence record you keep and file. — that part asks for a licence key.</div> | |
| <p class="note">Same engine as the VS Code extension, byte for byte.</p> | |
| </div> | |
| <script>var PLD_RULES = [ | |
| {"id": "undated_release", "sev": "high", "title": "Release entry carries no YYYY-MM-DD date", | |
| "why": "Art. 17(2) of Directive (EU) 2024/2853 runs the 10-year longstop from the day that version was placed on the market. An undated heading cannot prove that day."}, | |
| {"id": "void_disclaimer", "sev": "high", "title": "AS-IS / no-liability wording that Art. 15 voids", | |
| "why": "Art. 15 says liability towards an injured person may not be limited or excluded by a contractual provision. From 9 December 2026 the AS-IS clause stops doing the job it was written for."}, | |
| {"id": "security_fix_without_cve", "sev": "high", "title": "Security fix with no CVE or GHSA identifier", | |
| "why": "Art. 11(2)(c) keeps a defect in your control when it turns on software updates you did or did not supply. Without an identifier you cannot show which defect a release removed."}, | |
| {"id": "old_directive_citation", "sev": "high", "title": "Citation of the repealed 1985 Directive", | |
| "why": "Directive 85/374/EEC is repealed by Directive (EU) 2024/2853 with effect from 9 December 2026. A file that still cites it is describing a regime that has ended."}, | |
| {"id": "deadline_drift", "sev": "high", "title": "Product-liability date that is not 2026-12-09", | |
| "why": "Member States apply Directive (EU) 2024/2853 from 9 December 2026. Any other date on the same line is the single most copied mistake in generated text."}, | |
| {"id": "no_support_window", "sev": "high", "title": "No dated support window anywhere in the file", | |
| "why": "Annex II(8) of the Cyber Resilience Act (EU) 2024/2847 requires the end date of the support period in the information given to users, and Art. 11(2)(c) PLD reads that window as your evidence."}, | |
| {"id": "no_security_contact", "sev": "med", "title": "No vulnerability-reporting contact", | |
| "why": "Annex II(2) CRA requires a single point of contact for reporting. Since 11 September 2026 an actively exploited vulnerability must reach ENISA within 24 hours."}, | |
| {"id": "unversioned_heading", "sev": "med", "title": "Release heading names no version", | |
| "why": "Art. 4(1) treats each software version placed on the market as a product. 'Latest' and 'Current' identify no product."}, | |
| {"id": "stale_support_claim", "sev": "med", "title": "Active-support claim older than the last dated release", | |
| "why": "A support claim that the release history does not back is the gap Art. 11(2)(c) opens: the update was in your control and it did not arrive."}, | |
| {"id": "yanked_without_reason", "sev": "med", "title": "Version withdrawn with no recorded reason", | |
| "why": "Art. 8 lets a court order you to disclose the record. A withdrawal with no reason on it leaves the defect unexplained in your own file."}, | |
| {"id": "future_date", "sev": "low", "title": "Release dated after today", | |
| "why": "A product cannot be placed on the market in the future. The date decides the 10-year window under Art. 17(2), so a typo moves it."}, | |
| {"id": "vague_fix_language", "sev": "low", "title": "'Various fixes' with nothing named", | |
| "why": "Art. 10(2) lets a court presume defectiveness when ordered evidence is not produced. 'Various fixes' is not evidence of what was fixed."} | |
| ] | |
| ;</script> | |
| <script>/* EU Liability Window Lint — engine. | |
| Reads a CHANGELOG / release-notes file as text and reports the entries that | |
| will not carry a liability date, a support window or a named defect on | |
| 9 December 2026, the day Directive (EU) 2024/2853 starts to apply. */ | |
| var RULES = (typeof module !== 'undefined') ? require('./rules.json') : window.PLD_RULES; | |
| var PLD_APPLIES = '2026-12-09'; | |
| var RE_ISO = /\b(20\d{2})-(\d{2})-(\d{2})\b/; | |
| var RE_ISO_G = /\b20\d{2}-\d{2}-\d{2}\b/g; | |
| var RE_HEADING = /^\s{0,3}#{1,4}\s+\S/; | |
| var RE_VERSION = /\bv?\d+\.\d+(?:\.\d+)?(?:[-+][0-9A-Za-z.\-]+)?\b/; | |
| var RE_ID = /\b(?:CVE-\d{4}-\d{4,}|GHSA-[0-9a-z]{4}-[0-9a-z]{4}-[0-9a-z]{4})\b/i; | |
| var RE_DISCLAIM = /\bas[\s\-]is\b|\bno warrant|\bwithout warrant|\bnot liable\b|\bno liability\b|\bat your own risk\b|\bdisclaims?\b[^.]{0,40}\b(?:liability|warrant)|\blimitation of liability\b|\bin no event shall\b/i; | |
| var RE_SEC = /\b(?:security fix|security patch|security issue|vulnerabilit(?:y|ies)|exploit(?:ed|able)?|CVSS|RCE|XSS|CSRF|SSRF|SQL injection|buffer overflow|privilege escalation|remote code execution|denial of service|path traversal|auth bypass)\b/i; | |
| var RE_SEC_BULLET = /^\s*(?:[-*+]|\d+\.)\s+.*\bsecurity\b/i; | |
| var RE_OLD_DIR = /\b85\/374\/EEC\b|\b1999\/34\/EC\b|\bproduct liability directive\b[^.]{0,20}\b19\d{2}\b|\b1985\b[^.]{0,20}\bproduct liability\b/i; | |
| var RE_PLD = /\b2024\/2853\b|\bproduct liability directive\b|\bnew pld\b|\bPLD\b/i; | |
| var RE_SUPPORT = /\bsupported? until\b|\bsupport ends?\b|\bend[\s\-]of[\s\-]support\b|\bsecurity updates? until\b|\bsupport period\b|\bsupported through\b|\bEOL\b/i; | |
| var RE_CONTACT = /security@|SECURITY\.md|\breport a vulnerabilit|\bvulnerability disclosure\b|\bsecurity policy\b|\bsecurity advisor(?:y|ies)\b|\bcoordinated disclosure\b/i; | |
| var RE_ACTIVE = /\bactively maintained\b|\bactively supported\b|\bunder active development\b|\bfully supported\b|\bcurrently supported\b/i; | |
| var RE_YANK = /\byank(?:ed)?\b|\bwithdrawn\b|\brevoked\b|\bretracted\b|\bunpublished\b/i; | |
| var RE_REASON = /\bbecause\b|\breason\b|\bdue to\b|\bsee \b|\breplaced by\b|\bsuperseded by\b/i; | |
| var RE_VAGUE = /\b(?:various|misc|miscellaneous|minor|assorted|several|small|general)\s+(?:bug\s?)?(?:fixes|fixups|improvements|changes|updates|tweaks|cleanups)\b|^\s*(?:[-*+]|\d+\.)\s*(?:bug\s?fixes|fixes|improvements|updates|cleanup)\s*\.?\s*$/i; | |
| var RE_NOVERSION_HEAD = /^\s{0,3}#{1,4}\s*\[?\s*(?:latest|current|newest|recent|new release|this release|release|next)\s*\]?\s*[:\-]?\s*$/i; | |
| function daysBetween(a, b) { | |
| return Math.round((Date.parse(b + 'T00:00:00Z') - Date.parse(a + 'T00:00:00Z')) / 86400000); | |
| } | |
| function ruleById(id) { | |
| for (var i = 0; i < RULES.length; i++) { if (RULES[i].id === id) return RULES[i]; } | |
| return {id: id, sev: 'med', title: id, why: ''}; | |
| } | |
| function check(text, opts) { | |
| opts = opts || {}; | |
| var today = opts.today || '2026-09-16'; | |
| var lines = String(text == null ? '' : text).split(/\r?\n/); | |
| var findings = []; | |
| var seenSupport = false, seenContact = false; | |
| var newestRelease = null, activeClaimLine = 0, activeClaimText = ''; | |
| function push(id, line, msg) { | |
| var r = ruleById(id); | |
| findings.push({check: id, sev: r.sev, msg: msg, line: line}); | |
| } | |
| for (var i = 0; i < lines.length; i++) { | |
| var raw = lines[i], line = i + 1, t = raw.trim(); | |
| if (!t) continue; | |
| var isHeading = RE_HEADING.test(raw); | |
| var iso = raw.match(RE_ISO); | |
| var hasVersion = RE_VERSION.test(raw.replace(RE_ISO_G, '')); | |
| if (RE_SUPPORT.test(raw) && iso) seenSupport = true; | |
| if (RE_CONTACT.test(raw)) seenContact = true; | |
| /* 1. release heading with a version but no ISO date */ | |
| if (isHeading && hasVersion && !iso && !/\bunreleased\b/i.test(raw)) { | |
| push('undated_release', line, 'Release "' + t.replace(/^#+\s*/, '').slice(0, 48) + | |
| '" has no YYYY-MM-DD date. The 10-year liability window in Art. 17(2) of Directive (EU) 2024/2853 runs from the day this version was placed on the market, and this line does not record it.'); | |
| } | |
| /* 8. heading that names no version at all */ | |
| if (isHeading && RE_NOVERSION_HEAD.test(raw)) { | |
| push('unversioned_heading', line, 'Heading "' + t.replace(/^#+\s*/, '') + | |
| '" names no version. Art. 4(1) makes each version you place on the market its own product, so this entry belongs to nothing you can identify.'); | |
| } | |
| /* 2. disclaimer wording that Art. 15 voids */ | |
| if (RE_DISCLAIM.test(raw)) { | |
| push('void_disclaimer', line, 'Liability-exclusion wording here does not bind an injured person: Art. 15 of Directive (EU) 2024/2853 makes contractual limits void, and from ' + | |
| PLD_APPLIES + ' that is the law in every Member State.'); | |
| } | |
| /* 3. security work with no CVE/GHSA */ | |
| if (!isHeading && (RE_SEC.test(raw) || RE_SEC_BULLET.test(raw)) && !RE_ID.test(raw)) { | |
| push('security_fix_without_cve', line, 'Security change with no CVE or GHSA identifier. Art. 11(2)(c) keeps a defect in your control when it turns on updates you supplied, and this line names no defect to point at.'); | |
| } | |
| /* 4. repealed directive */ | |
| if (RE_OLD_DIR.test(raw)) { | |
| push('old_directive_citation', line, 'This cites Directive 85/374/EEC, which Directive (EU) 2024/2853 repeals with effect from ' + | |
| PLD_APPLIES + '. Software was not a product under the old text; it is one under Art. 4(1) of the new one.'); | |
| } | |
| /* 5. wrong applicability date next to the PLD */ | |
| if (RE_PLD.test(raw)) { | |
| var stripped = raw.replace(/2024\/2853/g, ' ').replace(/2024\/2847/g, ' ').replace(/85\/374\/EEC/gi, ' '); | |
| var years = stripped.match(/\b20\d{2}\b/g) || []; | |
| var isos = stripped.match(RE_ISO_G) || []; | |
| var bad = null; | |
| if (years.length && years.indexOf('2026') === -1) bad = years[0]; | |
| for (var k = 0; k < isos.length; k++) { if (isos[k].slice(0, 4) === '2026' && isos[k] !== PLD_APPLIES) bad = isos[k]; } | |
| if (bad) { | |
| push('deadline_drift', line, 'This puts the product-liability change at ' + bad + | |
| '. Member States apply Directive (EU) 2024/2853 from ' + PLD_APPLIES + '; a reader who trusts this line plans around the wrong quarter.'); | |
| } | |
| } | |
| /* 10. withdrawal with no reason */ | |
| if (RE_YANK.test(raw) && !RE_ID.test(raw) && !RE_REASON.test(raw)) { | |
| push('yanked_without_reason', line, 'A version is withdrawn here with no reason and no identifier. Under Art. 8 a court may order this record to be disclosed, and Art. 10(2) lets it presume the product was defective when the record does not answer.'); | |
| } | |
| /* 12. vague fix language */ | |
| if (!isHeading && RE_VAGUE.test(raw)) { | |
| push('vague_fix_language', line, '"' + t.replace(/^[-*+\s]+/, '').slice(0, 40) + | |
| '" names nothing that was fixed. Art. 10(2) allows a presumption of defectiveness when ordered evidence is not produced, and this entry produces none.'); | |
| } | |
| /* 11. future-dated release + newest release tracking */ | |
| if (iso) { | |
| var d = iso[0]; | |
| var isReleaseLine = isHeading || /\brelease[ds]?\b|\bpublish(?:ed)?\b|\bshipped\b/i.test(raw); | |
| if (isHeading && (!newestRelease || d > newestRelease)) newestRelease = d; | |
| if (isReleaseLine && d > today) { | |
| push('future_date', line, 'Dated ' + d + ', which is after today (' + today + | |
| '). The placing-on-the-market date starts the 10-year window in Art. 17(2), so a typo here moves the window.'); | |
| } | |
| } | |
| if (!activeClaimLine && RE_ACTIVE.test(raw)) { activeClaimLine = line; activeClaimText = t.slice(0, 40); } | |
| } | |
| /* 9. active-support claim the release history does not back */ | |
| if (activeClaimLine && newestRelease) { | |
| var gap = daysBetween(newestRelease, today); | |
| if (gap > 365) { | |
| push('stale_support_claim', activeClaimLine, 'This file claims active support, but the newest dated release is ' + | |
| newestRelease + ' — ' + gap + ' days ago. Art. 11(2)(c) treats the update you did not ship as being within your control.'); | |
| } | |
| } | |
| /* 6. no dated support window */ | |
| if (!seenSupport) { | |
| push('no_support_window', 1, 'No dated support window in this file. Annex II(8) of the Cyber Resilience Act (EU) 2024/2847 requires the end date of the support period in the information supplied to users, and that date is also the evidence Art. 11(2)(c) PLD asks for.'); | |
| } | |
| /* 7. no reporting contact */ | |
| if (!seenContact) { | |
| push('no_security_contact', 1, 'No vulnerability-reporting contact in this file. Annex II(2) CRA requires a single point of contact, and since 11 September 2026 an actively exploited vulnerability must reach ENISA within 24 hours.'); | |
| } | |
| findings.sort(function (a, b) { return a.line - b.line; }); | |
| return {findings: findings}; | |
| } | |
| var API = {engine: {check: check}, RULES: RULES, RULE_COUNT: RULES.length}; | |
| if (typeof module !== 'undefined') { module.exports = API; } | |
| if (typeof window !== 'undefined') { window.PLDENGINE = API; } | |
| </script> | |
| <script>// ⛔뼈대 — kit/scaffold.py 가 찍는다 (s143). findings [{check,sev,msg,line?}] → 글/HTML. 같은 파일이 Node 와 브라우저에서 산다. | |
| ; | |
| function escapeHtml(s) { return String(s == null ? '' : s).replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"'); } | |
| function summaryLine(res) { | |
| const f = (res && res.findings) || []; const e = f.filter(function (x) { return String(x.sev || 'error').toLowerCase().startsWith('err'); }).length; | |
| return f.length ? (f.length + ' finding' + (f.length === 1 ? '' : 's') + ' (' + e + ' error' + (e === 1 ? '' : 's') + ')') : 'Clean — no findings.'; | |
| } | |
| function toText(res, label) { | |
| const f = (res && res.findings) || []; | |
| const lines = ['== ' + (label || '') + ' — ' + summaryLine(res)]; | |
| f.forEach(function (x) { lines.push(' ' + String(x.sev || 'error').toUpperCase().slice(0, 4) + ' ' + (x.line ? 'L' + x.line + ' ' : '') + (x.check || x.id || '') + ' ' + (x.msg || x.message || '')); }); | |
| return lines.join('\n'); | |
| } | |
| function toHtml(res) { | |
| const f = (res && res.findings) || []; | |
| if (!f.length) return '<p class="ok">' + escapeHtml(summaryLine(res)) + '</p>'; | |
| const rows = f.map(function (x) { return '<tr><td class="sev ' + escapeHtml(String(x.sev || 'error')) + '">' + escapeHtml(String(x.sev || 'error')) + '</td><td>' + (x.line ? 'L' + escapeHtml(x.line) : '') + '</td><td><code>' + escapeHtml(x.check || x.id || '') + '</code></td><td>' + escapeHtml(x.msg || x.message || '') + '</td></tr>'; }).join(''); | |
| return '<p class="sum">' + escapeHtml(summaryLine(res)) + '</p><table><thead><tr><th>Level</th><th>Line</th><th>Check</th><th>What</th></tr></thead><tbody>' + rows + '</tbody></table>'; | |
| } | |
| var PLDREPORT = { escapeHtml: escapeHtml, summaryLine: summaryLine, toText: toText, toHtml: toHtml }; | |
| if (typeof module !== 'undefined' && module.exports) module.exports = PLDREPORT; | |
| else window.PLDREPORT = PLDREPORT; | |
| </script> | |
| <script> | |
| (function(){ | |
| var src=document.getElementById('src'), out=document.getElementById('out'), go=document.getElementById('go'), today=document.getElementById('today'); | |
| today.value=new Date().toISOString().slice(0,10); | |
| function run(){ try { var res=window.PLDENGINE.engine.check(src.value,{today:today.value}); out.innerHTML=window.PLDREPORT.toHtml(res); } catch(e){ out.innerHTML='<p class="sev error">Could not run: '+String(e.message||e)+'</p>'; } } | |
| go.onclick=run; if (src.value.trim()) run(); | |
| })(); | |
| </script> | |
| <section data-yj-install="free" style="margin:2rem auto 1rem;max-width:46rem;padding:1.25rem 1.25rem;border:1px solid #cfe3d6;border-radius:12px;background:#f6fbf8;font:16px/1.6 system-ui,-apple-system,Segoe UI,sans-serif"><h2 style="margin:0 0 .4rem;font-size:1.2rem">Install free</h2><p style="margin:0 0 .8rem;color:#41505f">Free for the file open in your editor - no key, no limit. The workspace sweep and the report ask for a key.</p><a href="https://marketplace.visualstudio.com/items?itemName=ReadyStack.pld-liability-window-lint" rel="noopener" data-yj-install-door="mp" onclick="try{navigator.sendBeacon('/api/ev',new Blob([JSON.stringify({t:'install',slug:'pld-liability-window-lint',src:'mp',path:location.pathname})],{type:'application/json'}))}catch(e){}" style="display:inline-block;margin:0 .5rem .5rem 0;padding:.6rem 1rem;border-radius:8px;background:#0f7b3f;color:#fff;text-decoration:none;font-weight:600">VS Code Marketplace</a><a href="https://open-vsx.org/extension/readystack/pld-liability-window-lint" rel="noopener" data-yj-install-door="ovsx" onclick="try{navigator.sendBeacon('/api/ev',new Blob([JSON.stringify({t:'install',slug:'pld-liability-window-lint',src:'ovsx',path:location.pathname})],{type:'application/json'}))}catch(e){}" style="display:inline-block;margin:0 .5rem .5rem 0;padding:.6rem 1rem;border-radius:8px;background:#0f7b3f;color:#fff;text-decoration:none;font-weight:600">Open VSX (Cursor, VSCodium)</a><a href="https://www.npmjs.com/package/@readystack/pld-liability-window-lint" rel="noopener" data-yj-install-door="npm" onclick="try{navigator.sendBeacon('/api/ev',new Blob([JSON.stringify({t:'install',slug:'pld-liability-window-lint',src:'npm',path:location.pathname})],{type:'application/json'}))}catch(e){}" style="display:inline-block;margin:0 .5rem .5rem 0;padding:.6rem 1rem;border-radius:8px;background:#0f7b3f;color:#fff;text-decoration:none;font-weight:600">npm</a><a href="https://www.npmjs.com/package/@readystack/pld-liability-window-lint" rel="noopener" data-yj-install-door="mcp" onclick="try{navigator.sendBeacon('/api/ev',new Blob([JSON.stringify({t:'install',slug:'pld-liability-window-lint',src:'mcp',path:location.pathname})],{type:'application/json'}))}catch(e){}" style="display:inline-block;margin:0 .5rem .5rem 0;padding:.6rem 1rem;border-radius:8px;background:#0f7b3f;color:#fff;text-decoration:none;font-weight:600">MCP server (npx)</a><a href="https://hub.docker.com/r/getreadystack/pld-liability-window-lint" rel="noopener" data-yj-install-door="docker" onclick="try{navigator.sendBeacon('/api/ev',new Blob([JSON.stringify({t:'install',slug:'pld-liability-window-lint',src:'docker',path:location.pathname})],{type:'application/json'}))}catch(e){}" style="display:inline-block;margin:0 .5rem .5rem 0;padding:.6rem 1rem;border-radius:8px;background:#0f7b3f;color:#fff;text-decoration:none;font-weight:600">Docker Hub</a><pre style="margin:.5rem 0 0;padding:.6rem .8rem;background:#f3f5f8;border-radius:8px;font-size:.9rem;overflow:auto">ext install ReadyStack.pld-liability-window-lint | |
| npx @readystack/pld-liability-window-lint <file> | |
| npx @readystack/pld-liability-window-lint --mcp</pre><p style="margin:.6rem 0 0;font-size:.92rem;color:#41505f"><a href="https://getreadystack.com/api/buy/cl/polar_cl_l6iN1uWt0FwWu7tBsczD0jWpP2vxFM54Wdwqb3KPi1G" rel="nofollow" style="color:#0f7b3f;text-decoration:underline">Team? One key for every ReadyStack linter, 5 seats, $149 once</a></p></section> | |
| <section data-yj-alert="rule" style="margin:1rem auto 1.5rem;max-width:46rem;padding:1.1rem 1.25rem;border:1px solid #d9dee6;border-radius:12px;background:#fbfcfd;font:15px/1.55 system-ui,-apple-system,Segoe UI,sans-serif"><b style="font-size:1.05rem">Get the full rule table as a PDF</b><div style="opacity:.78;margin:.35rem 0 .8rem">All 12 rules EU Liability Window Lint checks, each with its source and date, on printable pages you can hand to your team or auditor. We email it now, and once more only if a rule changes. No newsletter.</div><div style="display:flex;gap:8px;flex-wrap:wrap"><input id="yjae" type="email" placeholder="you@example.com" style="flex:1;min-width:210px;padding:11px 13px;border:1px solid rgba(140,150,165,.34);border-radius:8px;background:#fff;color:inherit"><button id="yjab" style="padding:11px 18px;border-radius:8px;border:0;cursor:pointer;background:#0f7b3f;color:#fff;font:600 15px system-ui,sans-serif">Email me the PDF</button></div><div id="yjao" hidden style="margin-top:.6rem;color:#0f7b3f">Sent. It arrives within the hour - check spam too.</div><script>(function(){var b=document.getElementById("yjab"),e=document.getElementById("yjae");if(!b||!e)return;b.addEventListener("click",function(){var v=e.value.trim();if(!/.+@.+\..+/.test(v))return;try{localStorage.setItem("yj_em","1");}catch(_){}fetch(location.origin+"/api/subscribe",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({email:v,slug:"pld-liability-window-lint",lang:"en",source:"rule_table"+((b.closest&&b.closest("section")&&b.closest("section").getAttribute("data-yj-moved"))?"_at_result":"")})}).then(function(r){var o=document.getElementById("yjao");o.hidden=false;if(!r.ok){o.textContent="Could not save - please try again.";}}).catch(function(){var o=document.getElementById("yjao");o.hidden=false;o.textContent="Could not save - please try again.";});});})();</script><script>(function(){var e=document.getElementById("yjae"),s=e&&e.closest?e.closest("section"):null,o=document.getElementById("out");if(!s||!o)return;var d=false;function mv(ev){if(d)return;if(ev&&ev.target&&s.contains(ev.target))return;d=true;var b=o;while(b.parentNode&&b.parentNode!==document.body&&b.parentNode.tagName!=="MAIN"&&b.parentNode.tagName!=="ARTICLE")b=b.parentNode;if(!b.parentNode||b===s||b.contains(s))return;try{b.parentNode.insertBefore(s,b.nextSibling);s.setAttribute("data-yj-moved","1");}catch(_){}}document.addEventListener("input",mv,true);document.addEventListener("change",mv,true);})();</script></section> | |
| <section data-yj-cta="paid" style="margin:3rem auto;max-width:46rem;padding:1.5rem 1.25rem;border:1px solid #d8dee9;border-radius:12px;background:#fbfcfe;font:16px/1.6 system-ui,-apple-system,Segoe UI,sans-serif"><h2 style="margin:0 0 .5rem;font-size:1.25rem">Get the complete version <span class="yj-price">$29</span></h2><p style="margin:.25rem 0 1rem;color:#41505f">This page is the working piece. The full pack has everything below.</p><p style="margin:0 0 1rem;color:#41505f">12 rules read your CHANGELOG.md the way Directive (EU) 2024/2853 will read it from 2026-12-09: undated releases lose the start of the 10-year window in Art. 17(2), and the AS-IS clause is vo</p><p style="margin:0 0 1rem;color:#5b6b7c;font-size:.94rem">One hour of EU product-compliance counsel bills around $300, and one repository's release history takes longer than an hour to read.</p><a href="https://getreadystack.com/api/buy/cl/polar_cl_SLbJNzFJbhPz5hbdDSJNmtMORqZFq3eprmVBa2NojFU" rel="nofollow" style="display:inline-block;padding:.7rem 1.3rem;border-radius:8px;background:#1b64f2;color:#fff;text-decoration:none;font-weight:600">Buy the full version — $29</a></section> | |
| <!--yj-share-s101--><div style="margin:28px 0 8px;text-align:center"><button id="yjcp" type="button" style="font:inherit;padding:10px 18px;border:1px solid #8884;border-radius:10px;background:transparent;cursor:pointer">Copy link</button><button id="yjimg" type="button" style="font:inherit;padding:10px 18px;margin-left:8px;border:1px solid #8884;border-radius:10px;background:transparent;cursor:pointer">Save result as image</button></div><script>(function(){var b=document.getElementById("yjimg");if(!b)return;b.addEventListener("click",function(){var o=document.getElementById("out");var txt=(o&&(o.innerText||o.textContent)||"").trim();if(!txt){b.textContent="(no result yet)";setTimeout(function(){b.textContent="Save result as image";},1500);return;}var lines=txt.split(String.fromCharCode(10)).filter(function(x){return x.trim();}).slice(0,10);var W=1200,P=56,c=document.createElement("canvas");c.width=W;var lh=38,H=P*2+70+lines.length*lh+60;c.height=H;var x=c.getContext("2d");x.fillStyle="#1a1512";x.fillRect(0,0,W,H);x.fillStyle="#f3e9d2";x.font="600 34px system-ui,Segoe UI,Arial";var t=(document.title||"").split("|")[0].trim();x.fillText(t.slice(0,54),P,P+34);x.font="22px ui-monospace,Menlo,Consolas,monospace";x.fillStyle="#e8dcc4";for(var i=0;i<lines.length;i++){x.fillText(lines[i].slice(0,88),P,P+70+i*lh+22);}x.font="600 22px system-ui,Segoe UI,Arial";x.fillStyle="#c9a227";var d=location.hostname.replace("www.","");x.fillText(d,W-P-x.measureText(d).width,H-P+6);c.toBlob(function(bl){var u=URL.createObjectURL(bl),a=document.createElement("a");a.href=u;a.download=(t||"result").replace(/[^a-z0-9]+/gi,"-").toLowerCase()+"-"+d+".png";document.body.appendChild(a);a.click();setTimeout(function(){URL.revokeObjectURL(u);a.remove();},2000);},"image/png");});})();</script><script>(function(){var b=document.getElementById("yjcp");if(!b)return;var t=b.textContent;b.addEventListener("click",function(){var u=location.href.split("#")[0];function d(){b.textContent="Link copied";setTimeout(function(){b.textContent=t;},1800);}if(navigator.clipboard&&navigator.clipboard.writeText){navigator.clipboard.writeText(u).then(d,function(){prompt("",u);});}else{prompt("",u);}});})();</script><div class="yj-home-find"><div class="yj-lgbar"><a href="/" class="yj-lg on">EN</a><a href="/de/" class="yj-lg">DE</a><a href="/ja/" class="yj-lg">JA</a><a href="/es/" class="yj-lg">ES</a><a href="/pt/" class="yj-lg">PT</a></div><section class="yj-find"><h2>Find a tool</h2><input id="yjq" type="search" autocomplete="off" placeholder="Type a product name, format or task"><div id="yjr"></div></section><style>.yj-lgbar{position:absolute;top:14px;right:18px;display:flex;gap:6px;z-index:60}.yj-lg{font:600 12px/1 system-ui,sans-serif;padding:6px 9px;border-radius:4px;text-decoration:none;color:#8b96a3;border:1px solid rgba(140,150,165,.28)}.yj-lg:hover{color:#e8eaed;border-color:rgba(160,175,195,.6)}.yj-lg.on{color:#0e1116;background:#cfd6de;border-color:#cfd6de}.yj-find{max-width:760px;margin:34px auto 8px;padding:0 20px}.yj-find h2{font:600 20px/1.3 system-ui,sans-serif;margin:0 0 10px}#yjq{width:100%;box-sizing:border-box;padding:13px 15px;font:400 15.5px system-ui,sans-serif;border:1px solid rgba(140,150,165,.34);border-radius:8px;background:rgba(255,255,255,.04);color:inherit}#yjq:focus{outline:none;border-color:#7FD1C4}#yjr{margin-top:10px;display:flex;flex-direction:column;gap:6px}#yjr a{display:flex;justify-content:space-between;gap:12px;padding:11px 14px;border:1px solid rgba(140,150,165,.22);border-radius:6px;text-decoration:none;font:400 14.5px/1.4 system-ui,sans-serif;color:inherit}#yjr a:hover{border-color:#7FD1C4}#yjr .pr{font:600 13px system-ui,sans-serif;color:#5fbf9a;white-space:nowrap}</style><script>(function(){var q=document.getElementById("yjq"),r=document.getElementById("yjr"),D=null;function load(){if(D)return Promise.resolve(D);return fetch("/search-index.json").then(function(x){return x.json();}).then(function(j){D=j;return j;}).catch(function(){D=[];return D;});}function esc(t){return String(t).replace(/[&<>"]/g,function(c){return {"&":"&","<":"<",">":">",'"':"""}[c];});}function run(){var v=q.value.trim().toLowerCase();if(v.length<2){r.innerHTML="";return;}load().then(function(j){var w=v.split(/\s+/),o=[];for(var i=0;i<j.length&&o.length<12;i++){var t=j[i].t.toLowerCase();var ok=true;for(var k=0;k<w.length;k++){if(t.indexOf(w[k])<0){ok=false;break;}}if(ok)o.push(j[i]);}r.innerHTML=o.length?o.map(function(x){return "<a href=\""+esc(x.u)+"\">"+"<span>"+esc(x.t)+"</span>"+(x.p?"<span class=\"pr\">$"+x.p+"</span>":"")+"</a>";}).join(""):"";});}q.addEventListener("input",run);q.addEventListener("focus",load);})();</script></div> | |
| <script data-yj="yj-view-beacon">(function(){try{var p=location.pathname;var k='yjv:'+p;if(sessionStorage.getItem(k))return;sessionStorage.setItem(k,'1');fetch('/api/ev',{method:'POST',keepalive:true,headers:{'Content-Type':'application/json'},body:JSON.stringify({path:p,lang:"en",ref:(document.referrer||''),src:(function(){try{return (new URLSearchParams(location.search).get('ref')||'').replace(/[^a-z_]/g,'').slice(0,12)}catch(e){return ''}})()})}).catch(function(){});}catch(e){}})();</script> | |
| <script data-yj="yj-use-beacon">(function(){try{var o=document.getElementById('out');if(!o)return;var p=location.pathname,k='yju:'+p,sent=false;function fire(){if(sent||sessionStorage.getItem(k))return;if(!(o.textContent||'').replace(/\s+/g,'').length)return;sent=true;sessionStorage.setItem(k,'1');fetch('/api/ev',{method:'POST',keepalive:true,headers:{'Content-Type':'application/json'},body:JSON.stringify({path:p,lang:"en",t:'use',src:(function(){try{return (new URLSearchParams(location.search).get('ref')||'').replace(/[^a-z_]/g,'').slice(0,12)}catch(e){return ''}})()})}).catch(function(){});}var mo=new MutationObserver(function(){fire();if(sent)mo.disconnect();});mo.observe(o,{childList:true,characterData:true,subtree:true});}catch(e){}})();</script> | |
| <section data-yj="yj-facts-v1" style="max-width:920px;margin:48px auto 0;padding:0 20px;font-family:system-ui,sans-serif"><style>.yj-article p{font:400 15.5px/1.7 system-ui,sans-serif;color:#26313b;margin:0 0 12px;max-width:72ch}.yj-article h2,.yj-article h3,.yj-article h4{font:600 17px/1.35 system-ui,sans-serif;color:#1b1f24;margin:22px 0 8px}.yj-article table{border-collapse:collapse;margin:10px 0 16px;font:14px/1.45 system-ui,sans-serif}.yj-article th,.yj-article td{border:1px solid #e2e6ea;padding:6px 10px;text-align:left}.yj-article th{background:#f4f6f8}.yj-article pre{background:#0f1720;color:#e6edf3;padding:12px 14px;border-radius:8px;overflow:auto;font:13px/1.5 ui-monospace,Menlo,monospace}.yj-article code{font:13px ui-monospace,Menlo,monospace;background:#f1f3f5;padding:1px 4px;border-radius:3px}.yj-article pre code{background:none;padding:0}.yj-article ul,.yj-article ol{font:15px/1.6 system-ui,sans-serif;color:#26313b}</style><p style="font:400 13px/1.5 system-ui,sans-serif;color:#6b7680;margin:0 0 14px"><time datetime="2026-09-16">Updated 2026-09-16</time> · ReadyStack</p><script type="application/ld+json">{"@context":"https://schema.org","@type":"WebPage","dateModified":"2026-09-16","author":{"@type":"Organization","name":"ReadyStack"}}</script><h2 style="font:600 21px/1.3 system-ui,sans-serif;margin:0 0 6px;color:#1b1f24">Worked example</h2><p style="font:400 14.5px/1.5 system-ui,sans-serif;margin:0 0 16px;color:#5b6570">Real numbers from this tool, line by line.</p><div class="yj-article"><p><img src="https://getreadystack.com/img/promo/sku79612_result_card.jpg" alt="EU Liability Window Lint" loading="lazy" style="max-width:100%;border-radius:6px"></p> | |
| <p>A Berlin release engineer ran 12 rules over a 25-line CHANGELOG.md this week and got 15 findings back — 8 of them high. The file was ordinary. That is the point.</p> | |
| <p>On 9 December 2026 every EU Member State applies Directive (EU) 2024/2853, and Directive 85/374/EEC — the 1985 text that never mentioned software — is repealed. Under Art. 4(1) of the new Directive, software is a product. Standalone, embedded, or a model. The release history you keep for your own convenience becomes a record about a product, and under Art. 8 a court can order you to produce it.</p> | |
| <p>Four lines change meaning that morning.</p> | |
| <p><strong>The undated heading.</strong> Art. 17(2) runs a ten-year liability window from the day a version was placed on the market. <code>## 2.4.0</code> records a version and not a day. The window still exists; it simply has no start you can point at, and the person pointing at it later will not be you.</p> | |
| <p><strong>"Provided AS IS, without warranty of any kind."</strong> Art. 15 is one sentence long: liability towards an injured person may not be limited or excluded by a contractual provision. The clause stays in your LICENSE. It keeps working between you and a counterparty who signed something. It stops working against an injured person, which is the only situation it was ever written for.</p> | |
| <p><strong>"Fixed a security issue."</strong> Art. 11(2)(c) keeps a defect within the manufacturer's control when it turns on software updates supplied or not supplied. That is the defence and the trap in the same clause: to use it you have to be able to say which defect a release removed. A CVE or GHSA identifier says it. "Security issue" says nothing.</p> | |
| <p><strong>The line that is missing.</strong> Annex II(8) of the Cyber Resilience Act (EU) 2024/2847 requires the end date of the support period in the information supplied to users. Art. 11(2)(c) reads the same window from the other side. Most changelogs state no end date at all, and since 11 September 2026 an actively exploited vulnerability has to reach ENISA within 24 hours — Annex II(2) wants a contact in the file for exactly that.</p> | |
| <p>EU Liability Window Lint runs those four facts plus eight more over the open file, in VS Code or in a browser, and hands back a line number and the article behind each finding. On the clean fixture shipped with it — 27 lines, dated releases, CVE-identified fixes, a support window running to 2028-06-30 — it returns 0 findings. On the dirty fixture, 25 lines, it returns 15, covering all 12 rules.</p> | |
| <p>Two of those rules exist because generated text gets them wrong in a specific, repeatable way. <code>deadline_drift</code> flags any line that puts the product-liability change at a date other than 2026-12-09; the sample file says "applies from 2027-06-01", which is the kind of sentence a model produces confidently. <code>old_directive_citation</code> flags text still pointing at 85/374/EEC. <code>stale_support_claim</code> measures the gap: the sample claims active support while its newest dated release sits 683 days behind today.</p> | |
| <p>None of this is legal advice, and the extension does not tell anyone whether they are liable. It tells them which line in their own file does not answer — which is the part a lawyer would otherwise bill for. One hour of EU product-compliance counsel runs around $300, and one repository's release history takes longer than an hour to read.</p> | |
| <p>The free tier finishes the job on one file: all 12 rules, every finding, no key. The $29 tier changes the axis rather than the depth — every changelog in the workspace in one pass, and a dated Markdown and CSV evidence record you keep and file, because Art. 8 asks for the record and not for a screenshot.</p></div><h2 style="font:600 19px/1.3 system-ui,sans-serif;margin:30px 0 10px;color:#1b1f24">15 seconds — what it actually does</h2><video controls muted playsinline preload="none" poster="/img/promo/sku79612_result_card.jpg" style="width:100%;max-width:360px;border-radius:10px;display:block;margin:0 auto"><source src="/media/sku79612_short.mp4" type="video/mp4"></video><h2 style="font:600 21px/1.3 system-ui,sans-serif;margin:34px 0 6px;color:#1b1f24">Questions people ask</h2><details style="border-bottom:1px solid #e6e9ed;padding:10px 0"><summary style="cursor:pointer;font:600 15px/1.4 system-ui,sans-serif;color:#1b1f24">What does EU Liability Window Lint actually do?</summary><p style="margin:8px 0 2px;font:400 14.5px/1.6 system-ui,sans-serif;color:#33404b">It reads a CHANGELOG.md or release-notes file and applies 12 rules drawn from Directive (EU) 2024/2853 and the Cyber Resilience Act (EU) 2024/2847. On the 25-line sample changelog shipped with it, it returns 15 findings: undated releases, an AS-IS clause that Art. 15 voids, security fixes with no CVE, and a citation of the repealed Directive 85/374/EEC.</p></details><details style="border-bottom:1px solid #e6e9ed;padding:10px 0"><summary style="cursor:pointer;font:600 15px/1.4 system-ui,sans-serif;color:#1b1f24">Who is this for?</summary><p style="margin:8px 0 2px;font:400 14.5px/1.6 system-ui,sans-serif;color:#33404b">Maintainers, release engineers and vendors who place software on the EU market and keep a changelog. From 9 December 2026 software is a product under Art. 4(1) of Directive (EU) 2024/2853, so the release history stops being housekeeping and becomes a record a court can order disclosed under Art. 8.</p></details><details style="border-bottom:1px solid #e6e9ed;padding:10px 0"><summary style="cursor:pointer;font:600 15px/1.4 system-ui,sans-serif;color:#1b1f24">Why will a free markdown linter not do this?</summary><p style="margin:8px 0 2px;font:400 14.5px/1.6 system-ui,sans-serif;color:#33404b">Markdown linters and spell-checkers read style. None of them know that Art. 15 voids an AS-IS clause against an injured person, that Directive 85/374/EEC is repealed on 2026-12-09, or that Annex II(8) of the Cyber Resilience Act wants a support-end date. A chatbot will cheerfully hand you the wrong applicability year.</p></details><details style="border-bottom:1px solid #e6e9ed;padding:10px 0"><summary style="cursor:pointer;font:600 15px/1.4 system-ui,sans-serif;color:#1b1f24">What is free and what does the paid version add?</summary><p style="margin:8px 0 2px;font:400 14.5px/1.6 system-ui,sans-serif;color:#33404b">Free: the open file, all 12 rules, every finding with its line number and the article behind it. The clean sample returns 0 findings and the dirty one returns 15. Paid, $29 once: every changelog in the workspace in one pass, plus a dated Markdown and CSV evidence record you keep and file.</p></details><details style="border-bottom:1px solid #e6e9ed;padding:10px 0"><summary style="cursor:pointer;font:600 15px/1.4 system-ui,sans-serif;color:#1b1f24">What would this cost if a person did it?</summary><p style="margin:8px 0 2px;font:400 14.5px/1.6 system-ui,sans-serif;color:#33404b">One hour of EU product-compliance counsel bills around $300, and reading one repository's release history takes longer than an hour. This lint costs $29 once, runs in the editor or in the browser, and re-runs on every release. one licence key per person or team seat.</p></details><details style="border-bottom:1px solid #e6e9ed;padding:10px 0"><summary style="cursor:pointer;font:600 15px/1.4 system-ui,sans-serif;color:#1b1f24">Why not just ask ChatGPT or another AI chat?</summary><p style="margin:8px 0 2px;font:400 14.5px/1.6 system-ui,sans-serif;color:#33404b">A general AI chat answers from training data with a cutoff date, cannot read your repository and names no rule version. EU Liability Window Lint checks the file you open against 12 rules from a rule set dated 2026-09-20, and points at the exact line. For a filing, an audit or a client you need that dated result on your own files.</p></details><script type="application/ld+json" data-yj="yj-faq-ld">{"@context": "https://schema.org", "@type": "FAQPage", "mainEntity": [{"@type": "Question", "name": "What does EU Liability Window Lint actually do?", "acceptedAnswer": {"@type": "Answer", "text": "It reads a CHANGELOG.md or release-notes file and applies 12 rules drawn from Directive (EU) 2024/2853 and the Cyber Resilience Act (EU) 2024/2847. On the 25-line sample changelog shipped with it, it returns 15 findings: undated releases, an AS-IS clause that Art. 15 voids, security fixes with no CVE, and a citation of the repealed Directive 85/374/EEC."}}, {"@type": "Question", "name": "Who is this for?", "acceptedAnswer": {"@type": "Answer", "text": "Maintainers, release engineers and vendors who place software on the EU market and keep a changelog. From 9 December 2026 software is a product under Art. 4(1) of Directive (EU) 2024/2853, so the release history stops being housekeeping and becomes a record a court can order disclosed under Art. 8."}}, {"@type": "Question", "name": "Why will a free markdown linter not do this?", "acceptedAnswer": {"@type": "Answer", "text": "Markdown linters and spell-checkers read style. None of them know that Art. 15 voids an AS-IS clause against an injured person, that Directive 85/374/EEC is repealed on 2026-12-09, or that Annex II(8) of the Cyber Resilience Act wants a support-end date. A chatbot will cheerfully hand you the wrong applicability year."}}, {"@type": "Question", "name": "What is free and what does the paid version add?", "acceptedAnswer": {"@type": "Answer", "text": "Free: the open file, all 12 rules, every finding with its line number and the article behind it. The clean sample returns 0 findings and the dirty one returns 15. Paid, $29 once: every changelog in the workspace in one pass, plus a dated Markdown and CSV evidence record you keep and file."}}, {"@type": "Question", "name": "What would this cost if a person did it?", "acceptedAnswer": {"@type": "Answer", "text": "One hour of EU product-compliance counsel bills around $300, and reading one repository's release history takes longer than an hour. This lint costs $29 once, runs in the editor or in the browser, and re-runs on every release. one licence key per person or team seat."}}, {"@type": "Question", "name": "Why not just ask ChatGPT or another AI chat?", "acceptedAnswer": {"@type": "Answer", "text": "A general AI chat answers from training data with a cutoff date, cannot read your repository and names no rule version. EU Liability Window Lint checks the file you open against 12 rules from a rule set dated 2026-09-20, and points at the exact line. For a filing, an audit or a client you need that dated result on your own files."}}]}</script><div id="yj-ask" style="margin:36px 0 0;padding:18px 18px 16px;border:1px solid #e2e6ea;border-radius:10px;background:#fbfbfc"><h2 style="font:600 19px/1.3 system-ui,sans-serif;margin:0 0 4px;color:#1b1f24">Ask about this tool</h2><p style="font:400 13.5px/1.5 system-ui,sans-serif;margin:0 0 12px;color:#5b6570">One question, answered by the person who built it. Your email only if you want the answer sent.</p><form onsubmit="return yjAsk(event)" style="display:grid;gap:8px"><textarea name="question" required minlength="10" maxlength="2000" rows="3" placeholder="Your question" style="font:14px/1.5 system-ui,sans-serif;padding:10px;border:1px solid #cfd6dd;border-radius:6px"></textarea><div style="display:flex;gap:8px;flex-wrap:wrap"><input type="email" name="email" placeholder="Email (optional)" style="flex:1;min-width:200px;font:14px system-ui,sans-serif;padding:9px 10px;border:1px solid #cfd6dd;border-radius:6px"><button type="submit" style="font:600 14px system-ui,sans-serif;padding:9px 18px;border:0;border-radius:6px;background:#1b1f24;color:#fff;cursor:pointer">Send</button></div><p id="yj-ask-msg" style="font:13px system-ui,sans-serif;margin:2px 0 0;color:#0a6238;min-height:1em"></p></form><script>function yjAsk(e){e.preventDefault();var f=e.target,m=document.getElementById("yj-ask-msg");m.style.color="#0a6238";fetch(location.origin+"/api/ask",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({sku:79612,slug:"pld-liability-window-lint",lang:"en",question:f.question.value,email:f.email.value,page:location.pathname})}).then(function(r){if(!r.ok)throw 0;m.textContent="Thanks \u2014 noted. Answers land on this page and, if you left an email, in your inbox.";f.question.value="";}).catch(function(){m.style.color="#a8551f";m.textContent="Could not send. Please try again in a minute.";});return false;}</script></div></section><section class="yj-related" style="max-width:920px;margin:56px auto 40px;padding:0 20px"><h2 style="font:600 21px/1.3 system-ui,sans-serif;margin:0 0 6px;color:#1b1f24">Same job, next tool</h2><p style="font:400 14.5px/1.5 system-ui,sans-serif;margin:0 0 20px;color:#5b6570">Free in the browser. The full version is a one-time licence.</p><div style="display:grid;grid-template-columns:repeat(auto-fill,minmax(250px,1fr));gap:14px"><a class="yj-rel-c" href="https://getreadystack.com/tools/dora-ict-contract-clause-lint"><span class="yj-rel-t">DORA Art. 30 ICT Contract Clause Lint</span><span class="yj-rel-p">$29</span></a><a class="yj-rel-c" href="https://getreadystack.com/tools/en301549-lint"><span class="yj-rel-t">EN 301 549 Lint — European Accessibility Act rules, with the clause number, in</span><span class="yj-rel-p">$29</span></a><a class="yj-rel-c" href="https://getreadystack.com/tools/eu-repair-guarantee-tail-2026"><span class="yj-rel-t">EU Repair Guarantee Tail 2026 - date the 12 months every repair adds (Directiv</span><span class="yj-rel-p">$60</span></a><a class="yj-rel-c" href="https://getreadystack.com/tools/dotnet-eol-support-gate"><span class="yj-rel-t">.NET EOL & CRA Support Window Gate</span><span class="yj-rel-p">$29</span></a><a class="yj-rel-c" href="https://getreadystack.com/tools/robots-txt-ai-crawler-audit"><span class="yj-rel-t">AI Crawler Rules - robots.txt Audit for AI Search</span><span class="yj-rel-p">$29</span></a><a class="yj-rel-c" href="https://getreadystack.com/tools/ai-disclosure-lint-sb942"><span class="yj-rel-t">AI Output Disclosure Lint SB 942</span><span class="yj-rel-p">$29</span></a></div><style>.yj-rel-c{display:flex;flex-direction:column;gap:8px;padding:15px 16px;border:1px solid #e2e6ea;border-radius:6px;text-decoration:none;background:#fff}.yj-rel-c:hover{border-color:#b9c2cb;background:#fafbfc}.yj-rel-t{font:500 14.5px/1.42 system-ui,sans-serif;color:#1b1f24}.yj-rel-p{font:600 13px system-ui,sans-serif;color:#0a6238}</style></section></body> | |
| </html> | |