From 719ef31ba36590d29b9499e01398837b064c5fe3 Mon Sep 17 00:00:00 2001 From: Elmehdi Aitbrahim Date: Thu, 20 Aug 2026 17:29:21 -0400 Subject: [PATCH] feat(install): Windows is unsigned too, and the path with no warning goes first Three changes to the unsigned-build note. WINDOWS SIGNING IS DROPPED AS WELL. Azure Trusted Signing is ~$120/yr -- more than Apple's $99 -- and since 2024 it does not even buy an instant SmartScreen pass, because reputation is earned from download volume over time. Paying more to still be warned about is the worst of the three options. The note named only the Apple cost, which left a reader to assume Windows had simply been forgotten; it now names both and says which is which. THE NO-WARNING PATH LEADS. It was at the bottom of the note, after the certificate explanation and the list of what the warning does not mean. Someone reading this is deciding whether to click past a security warning, and "there is a route with no warning at all" is the most useful thing to hand them at that exact moment -- not four paragraphs about what Apple charges. It is set apart at the top now, and still honest about the trade rather than selling it: that route needs a terminal and Python 3.11+, which is precisely the friction the desktop app exists to remove. AND THE STEPS ARE ACTUALLY STEPS. "Click Open Anyway" is not instructions for someone who has never done it. macOS now runs from opening the .dmg through both confirmations, and says that on Sequoia and later the right-click-Open shortcut no longer works -- Apple removed it deliberately, and a page still recommending it sends people in a circle. Windows gets the step that matters and is easiest to miss: Unblock the .zip in Properties BEFORE extracting. Skip it and Windows marks every extracted file, so the prompt returns on a later launch and the user concludes the first bypass did not take. It also says to extract somewhere the user owns and NOT into Program Files, because keel does not need administrator rights and should not be given them. The two step lists are stacked rather than columned now -- they are long enough that side-by-side would put step 6 of one beside step 2 of the other and read as a single list. en/ar/fr, all revs moved together. `astro check` clean (0 errors, 77 files); verified in a build with platform bundles present that all three locales lead with the no-warning path and carry the Unblock and Program Files steps. --- src/components/pages/InstallPage.astro | 37 +++++++------ src/i18n/pages/install.ts | 76 ++++++++++++++++---------- src/styles/global.css | 21 +++++-- 3 files changed, 81 insertions(+), 53 deletions(-) diff --git a/src/components/pages/InstallPage.astro b/src/components/pages/InstallPage.astro index 05ba480..29b4db7 100644 --- a/src/components/pages/InstallPage.astro +++ b/src/components/pages/InstallPage.astro @@ -145,19 +145,28 @@ const venvCommands = (os: "mac" | "win"): string => { hasPlatformBundle && (

{c.unsigned.title}

+ + {/* FIRST, before any of the certificate explanation. Someone reading this is deciding + whether to proceed past a security warning, and "there is a route with no warning + at all" is the most useful thing to hand them at that exact moment -- not four + paragraphs about what Apple charges. It is honest about the trade rather than + selling it: that route needs a terminal, which is the friction the desktop app + exists to remove. */} +
+

{c.unsigned.avoidTitle}

+

{c.unsigned.avoidBody}

+

{c.unsigned.avoidLink} →

+
+

{c.unsigned.lead}

{c.unsigned.reason}

-
-
-

{c.unsigned.macosTitle}

-
    {c.unsigned.macosSteps.map((step) =>
  1. {step}
  2. )}
-
-
-

{c.unsigned.windowsTitle}

-
    {c.unsigned.windowsSteps.map((step) =>
  1. {step}
  2. )}
-
-
+ {/* Stacked, not columned: the steps are long enough now that two columns would put + step 6 of one beside step 2 of the other and read as one list. */} +

{c.unsigned.macosTitle}

+
    {c.unsigned.macosSteps.map((step) =>
  1. {step}
  2. )}
+

{c.unsigned.windowsTitle}

+
    {c.unsigned.windowsSteps.map((step) =>
  1. {step}
  2. )}

{c.unsigned.verifyTitle}

{c.unsigned.verifyLead}

@@ -167,14 +176,6 @@ const venvCommands = (os: "mac" | "win"): string => {

{c.unsigned.notMeaningTitle}

- {/* The friction-free alternative, offered here rather than left further down the - page: someone reading a security warning is deciding whether to proceed, and - "there is a path with no warning at all" is the most useful thing to hand them - at that exact moment. */} -

{c.unsigned.avoidTitle}

-

{c.unsigned.avoidBody}

-

{c.unsigned.avoidLink} →

-

{c.unsigned.more} → diff --git a/src/i18n/pages/install.ts b/src/i18n/pages/install.ts index 651232a..bf4ac38 100644 --- a/src/i18n/pages/install.ts +++ b/src/i18n/pages/install.ts @@ -76,7 +76,7 @@ export interface InstallContent { export const install: LocalizedPage = { en: { - rev: "2026-08-20.3", + rev: "2026-08-20.4", title: "Download keel — macOS & Windows", description: "Download keel for macOS or Windows. Version and links come from GitHub Releases at build time; the five-minute source path is here too.", @@ -119,18 +119,24 @@ export const install: LocalizedPage = { title: "Your computer will warn you about this download", lead: "The macOS and Windows builds are not code-signed, so your operating system will refuse the first open and tell you it cannot verify the developer. Nothing is broken, and nothing was detected — your computer simply does not know who wrote the program.", reason: - "Code signing is a paid certificate. Apple's costs $99 per year, every year, and keel cannot currently afford it. There is no cheaper tier and no free option for open-source projects, and a certificate we made ourselves would do nothing at all, because macOS trusts only certificates Apple issued.", + "Code signing is a paid certificate, and keel cannot currently afford either one: Apple's is $99 per year, and Azure Trusted Signing for Windows is about $120 per year — more than Apple's, and since 2024 it does not even buy an instant SmartScreen pass, because reputation is earned from download volume over time. There is no cheaper tier and no free open-source option on either platform, and a certificate we made ourselves would do nothing at all, because macOS trusts only certificates Apple issued.", macosTitle: "macOS", macosSteps: [ - "Double-click keel. macOS refuses, saying it cannot verify the developer.", + "Open the downloaded .dmg, then drag keel.app into your Applications folder.", + "Eject the disk image.", + "Open Applications and double-click keel. macOS refuses; click Done.", "Open System Settings → Privacy & Security.", - "Scroll to the message about keel and click Open Anyway.", - "You only do this once.", + "Scroll to the Security section. There is a line saying keel was blocked, with an Open Anyway button beside it. Click it.", + "Authenticate, then click Open Anyway once more in the dialog that follows.", + "You only do this once. On macOS Sequoia (15) and later, right-clicking the app and choosing Open no longer works as a shortcut — Apple removed that path deliberately.", ], windowsTitle: "Windows", windowsSteps: [ - "Run the installer. SmartScreen says \"Windows protected your PC\".", - "Click More info, then Run anyway.", + "Before extracting, right-click the downloaded .zip → Properties.", + "At the bottom of the General tab, tick Unblock if it is there, then OK. This is the step people miss, and skipping it brings the warning back on a later launch.", + "Right-click the .zip → Extract All…, into a folder you own — for example C:\\Users\\\\keel. Not Program Files: keel does not need administrator rights and should not be given them.", + "Open the extracted folder and double-click keel.exe.", + "If SmartScreen appears — \"Windows protected your PC\" — click More info, then Run anyway.", ], verifyTitle: "Please check what you downloaded first", verifyLead: @@ -143,17 +149,17 @@ export const install: LocalizedPage = { "It does not mean your computer found something wrong. Nothing was scanned and nothing was detected.", "It does not mean the app behaves differently. A signed and an unsigned build of the same release are the same program.", ], - avoidTitle: "Or skip the warning entirely", + avoidTitle: "First — you may not need to deal with this at all", avoidBody: - "The five-minute source path below installs the same engine with no installer and no warning, because nothing is downloaded as an application — pip and uv fetch the published wheels directly. It needs a terminal and Python 3.11+, which is exactly the friction the desktop app exists to remove; but if you already have both, it is the shorter road.", + "The five-minute path below installs the same engine with no installer and no warning on any platform, because nothing is downloaded as an application — pip and uv fetch the published wheels directly, and no operating system objects to that. It needs a terminal and Python 3.11 or later, which is exactly the friction the desktop app exists to remove; but if you already have both, it is the shorter road and the rest of this note does not apply to you.", avoidLink: "Try it in five minutes", more: "Full explanation, including how to verify what you downloaded", }, }, ar: { - rev: "2026-08-20.3", - translatedFromRev: "2026-08-20.3", + rev: "2026-08-20.4", + translatedFromRev: "2026-08-20.4", title: "تنزيل كيل — macOS وWindows", description: "نزّل كيل لـ macOS أو Windows. الإصدار والروابط من GitHub Releases وقت البناء؛ ومسار المصدر في خمس دقائق هنا أيضًا.", @@ -196,18 +202,24 @@ export const install: LocalizedPage = { title: "سيحذّرك جهازك من هذا التنزيل", lead: "بِنى macOS وWindows غير موقّعة رقميًّا، لذا سيرفض نظامك فتحها أول مرّة ويقول إنه لا يستطيع التحقّق من المطوّر. لا شيء معطّل، ولم يُكتشف شيء — جهازك ببساطة لا يعرف من كتب البرنامج.", reason: - "التوقيع الرقمي شهادةٌ مدفوعة. شهادة Apple تكلّف 99 دولارًا سنويًّا، كلّ سنة، وكيل لا يقدر عليها حاليًّا. ولا توجد فئة أرخص ولا خيارٌ مجانيٌّ لمشاريع المصدر المفتوح، وشهادةٌ نصنعها بأنفسنا لا تفيد شيئًا البتّة، لأن macOS لا يثق إلا بالشهادات الصادرة عن Apple.", + "التوقيع الرقمي شهادةٌ مدفوعة، وكيل لا يقدر على أيٍّ منهما حاليًّا: شهادة Apple بـ99 دولارًا سنويًّا، وAzure Trusted Signing لويندوز بنحو 120 دولارًا سنويًّا — أغلى من Apple، ومنذ 2024 لا تمنح حتى تجاوزًا فوريًّا لـSmartScreen، لأن السمعة تُكتسب من حجم التنزيلات عبر الوقت. ولا توجد فئة أرخص ولا خيارٌ مجانيٌّ لمشاريع المصدر المفتوح على أيٍّ من النظامين، وشهادةٌ نصنعها بأنفسنا لا تفيد شيئًا البتّة، لأن macOS لا يثق إلا بالشهادات الصادرة عن Apple.", macosTitle: "macOS", macosSteps: [ - "انقر كيل نقرًا مزدوجًا. سيرفض macOS قائلًا إنه لا يستطيع التحقّق من المطوّر.", + "افتح ملفّ ‎.dmg المنزَّل، ثم اسحب ‏keel.app إلى مجلّد ‏Applications.", + "أخرِج قرص التثبيت (Eject).", + "افتح ‏Applications وانقر كيل نقرًا مزدوجًا. سيرفض macOS؛ اضغط ‏Done.", "افتح ‏System Settings ← Privacy & Security.", - "انزل إلى الرسالة الخاصّة بكيل واضغط ‏Open Anyway.", - "تفعل هذا مرّةً واحدة فقط.", + "انزل إلى قسم ‏Security. ستجد سطرًا يقول إن كيل حُجب، وبجانبه زرّ ‏Open Anyway. اضغطه.", + "أثبِت هويّتك، ثم اضغط ‏Open Anyway مرّةً أخرى في النافذة التي تظهر.", + "تفعل هذا مرّةً واحدة فقط. وفي macOS Sequoia‏ (15) فما بعد، لم يعد النقر بالزرّ الأيمن واختيار ‏Open يعمل كاختصار — أزالت Apple هذا المسار عمدًا.", ], windowsTitle: "Windows", windowsSteps: [ - "شغّل المثبّت. سيقول ‏SmartScreen‏: «‏Windows protected your PC‏».", - "اضغط ‏More info ثم ‏Run anyway.", + "قبل فكّ الضغط، انقر بالزرّ الأيمن على ملفّ ‎.zip المنزَّل ← ‏Properties.", + "في أسفل تبويب ‏General، علّم ‏Unblock إن وُجد ثم ‏OK. هذه هي الخطوة التي يغفلها الناس، وتخطّيها يُعيد التحذير عند تشغيلٍ لاحق.", + "انقر بالزرّ الأيمن على ‎.zip ← ‏Extract All…‎ إلى مجلّدٍ تملكه — مثلًا ‏C:\\\\Users\\\\<اسمك>\\\\keel. وليس ‏Program Files: كيل لا يحتاج صلاحيات المسؤول ولا ينبغي منحه إيّاها.", + "افتح المجلّد المستخرَج وانقر ‏keel.exe نقرًا مزدوجًا.", + "إن ظهر ‏SmartScreen — «‏Windows protected your PC‏» — فاضغط ‏More info ثم ‏Run anyway.", ], verifyTitle: "من فضلك تحقّق ممّا نزّلته أولًا", verifyLead: @@ -220,17 +232,17 @@ export const install: LocalizedPage = { "لا يعني أن جهازك وجد خطبًا ما. لم يُفحص شيء ولم يُكتشف شيء.", "لا يعني أن التطبيق يسلك سلوكًا مختلفًا. البنية الموقّعة وغير الموقّعة من الإصدار نفسه هما البرنامج نفسه.", ], - avoidTitle: "أو تجاوز التحذير من أصله", + avoidTitle: "أولًا — قد لا تحتاج إلى التعامل مع هذا أصلًا", avoidBody: - "مسار المصدر في خمس دقائق أدناه يثبّت المحرّك نفسه بلا مثبّت وبلا تحذير، لأنه لا يُنزَّل شيءٌ بوصفه تطبيقًا — بل يجلب pip وuv العجلات المنشورة مباشرةً. يحتاج طرفيّةً وPython 3.11 فأحدث، وهو بالضبط الاحتكاك الذي وُجد تطبيق سطح المكتب ليزيله؛ لكن إن كان كلاهما عندك أصلًا فهو الطريق الأقصر.", + "مسار الخمس دقائق أدناه يثبّت المحرّك نفسه بلا مثبّت وبلا تحذيرٍ على أيّ نظام، لأنه لا يُنزَّل شيءٌ بوصفه تطبيقًا — بل يجلب pip وuv العجلات المنشورة مباشرةً، ولا يعترض أيّ نظام تشغيل على ذلك. يحتاج طرفيّةً وPython 3.11 فأحدث، وهو بالضبط الاحتكاك الذي وُجد تطبيق سطح المكتب ليزيله؛ لكن إن كان كلاهما عندك أصلًا فهو الطريق الأقصر، وبقيّة هذه الملاحظة لا تعنيك.", avoidLink: "جرّبه في خمس دقائق", more: "الشرح الكامل، وكيف تتحقّق ممّا نزّلته", }, }, fr: { - rev: "2026-08-20.3", - translatedFromRev: "2026-08-20.3", + rev: "2026-08-20.4", + translatedFromRev: "2026-08-20.4", title: "Télécharger keel — macOS et Windows", description: "Téléchargez keel pour macOS ou Windows. Version et liens viennent de GitHub Releases au build ; le parcours en cinq minutes depuis les sources est là aussi.", @@ -273,18 +285,24 @@ export const install: LocalizedPage = { title: "Votre ordinateur va vous avertir à propos de ce téléchargement", lead: "Les builds macOS et Windows ne sont pas signés, donc votre système refusera la première ouverture en disant qu'il ne peut pas vérifier le développeur. Rien n'est cassé et rien n'a été détecté — votre ordinateur ne sait simplement pas qui a écrit le programme.", reason: - "La signature de code est un certificat payant. Celui d'Apple coûte 99 $ par an, chaque année, et keel n'en a pas les moyens aujourd'hui. Il n'existe ni offre moins chère ni option gratuite pour les projets open source, et un certificat que nous fabriquerions nous-mêmes ne servirait à rien : macOS ne fait confiance qu'aux certificats émis par Apple.", + "La signature de code est un certificat payant, et keel n'a les moyens ni de l'un ni de l'autre : celui d'Apple coûte 99 $ par an, et Azure Trusted Signing pour Windows environ 120 $ par an — plus cher qu'Apple, et depuis 2024 il n'accorde même pas de passe-droit immédiat auprès de SmartScreen, la réputation s'acquérant au volume de téléchargements dans le temps. Il n'existe ni offre moins chère ni option gratuite pour l'open source sur l'une ou l'autre plateforme, et un certificat que nous fabriquerions nous-mêmes ne servirait à rien : macOS ne fait confiance qu'aux certificats émis par Apple.", macosTitle: "macOS", macosSteps: [ - "Double-cliquez sur keel. macOS refuse, en disant qu'il ne peut pas vérifier le développeur.", + "Ouvrez le .dmg téléchargé, puis glissez keel.app dans votre dossier Applications.", + "Éjectez l'image disque.", + "Ouvrez Applications et double-cliquez sur keel. macOS refuse ; cliquez sur Terminé.", "Ouvrez Réglages Système → Confidentialité et sécurité.", - "Descendez jusqu'au message concernant keel et cliquez sur Ouvrir quand même.", - "Vous ne le faites qu'une seule fois.", + "Descendez jusqu'à la section Sécurité. Une ligne indique que keel a été bloqué, avec un bouton Ouvrir quand même à côté. Cliquez dessus.", + "Authentifiez-vous, puis cliquez encore une fois sur Ouvrir quand même dans la boîte de dialogue qui suit.", + "Vous ne le faites qu'une seule fois. Sur macOS Sequoia (15) et versions ultérieures, le clic droit puis Ouvrir ne fonctionne plus comme raccourci — Apple a supprimé ce chemin délibérément.", ], windowsTitle: "Windows", windowsSteps: [ - "Lancez l'installeur. SmartScreen affiche « Windows a protégé votre ordinateur ».", - "Cliquez sur Informations complémentaires, puis Exécuter quand même.", + "Avant d'extraire, clic droit sur le .zip téléchargé → Propriétés.", + "En bas de l'onglet Général, cochez Débloquer si la case est présente, puis OK. C'est l'étape que l'on oublie, et la sauter fait revenir l'avertissement à un lancement ultérieur.", + "Clic droit sur le .zip → Extraire tout…, vers un dossier qui vous appartient — par exemple C:\\\\Users\\\\\\\\keel. Pas Program Files : keel n'a pas besoin des droits administrateur et ne doit pas les recevoir.", + "Ouvrez le dossier extrait et double-cliquez sur keel.exe.", + "Si SmartScreen apparaît — « Windows a protégé votre ordinateur » — cliquez sur Informations complémentaires, puis Exécuter quand même.", ], verifyTitle: "Vérifiez d'abord ce que vous avez téléchargé", verifyLead: @@ -297,9 +315,9 @@ export const install: LocalizedPage = { "Cela ne signifie pas que votre ordinateur a trouvé un problème. Rien n'a été analysé et rien n'a été détecté.", "Cela ne signifie pas que l'application se comporte différemment. Un build signé et un build non signé de la même version sont le même programme.", ], - avoidTitle: "Ou évitez complètement l'avertissement", + avoidTitle: "D'abord — vous n'avez peut-être pas à vous en occuper", avoidBody: - "Le parcours en cinq minutes depuis les sources, ci-dessous, installe le même moteur sans installeur et sans avertissement, parce que rien n'est téléchargé en tant qu'application — pip et uv récupèrent directement les wheels publiées. Il faut un terminal et Python 3.11+, ce qui est précisément la friction que l'application de bureau existe pour supprimer ; mais si vous avez déjà les deux, c'est le chemin le plus court.", + "Le parcours en cinq minutes ci-dessous installe le même moteur sans installeur et sans avertissement, sur aucune plateforme, parce que rien n'est téléchargé en tant qu'application — pip et uv récupèrent directement les wheels publiées, et aucun système d'exploitation n'y objecte. Il faut un terminal et Python 3.11 ou plus, ce qui est précisément la friction que l'application de bureau existe pour supprimer ; mais si vous avez déjà les deux, c'est le chemin le plus court et le reste de cette note ne vous concerne pas.", avoidLink: "Essayez-le en cinq minutes", more: "Explication complète, et comment vérifier ce que vous avez téléchargé", }, diff --git a/src/styles/global.css b/src/styles/global.css index d5f77f1..15eb931 100644 --- a/src/styles/global.css +++ b/src/styles/global.css @@ -949,14 +949,23 @@ section { margin-block: 1.4rem 0.4rem; } -.unsigned-steps { - display: grid; - grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr)); - gap: 0 2rem; +/* The no-warning route, set apart at the top of the note: it is an answer, not a caveat. */ +.unsigned-first { + border-inline-start: 3px solid var(--accent, currentColor); + padding-inline-start: 1rem; + margin-block: 1rem 1.6rem; +} + +.unsigned-first h3 { + margin-top: 0; +} + +.unsigned-note ol { + padding-inline-start: 1.4rem; } -.unsigned-steps h3 { - margin-top: 1.2rem; +.unsigned-note ol li { + margin-block: 0.35rem; } .verify-command {