From a25a9c32e51b7f983da1abe2b003cd35fd38aff0 Mon Sep 17 00:00:00 2001 From: promisepreston Date: Sat, 15 Aug 2026 14:18:05 +0200 Subject: [PATCH 1/5] docs: explain Gatekeeper Open Anyway recovery --- INSTALL.md | 14 ++++++++++---- README.md | 2 +- site/install.html | 2 +- test/site.test.mjs | 21 ++++++++++++++++++--- 4 files changed, 30 insertions(+), 9 deletions(-) diff --git a/INSTALL.md b/INSTALL.md index d705ea9..ec01009 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -24,11 +24,17 @@ The Downloads page shows the exact SHA-256 checksum for every preview. If you ar ## First launch 1. Open **Applications** in Finder. -2. Hold the Control key while clicking **RecordCove**, then select **Open**. -3. macOS explains that Apple cannot verify the developer. Select **Open** only if the file and checksum match the preview page. -4. RecordCove should open. If macOS says the app is damaged, stop and tell the maintainer. +2. Double-click **RecordCove** once. macOS may explain that Apple cannot verify the app is free of malware. +3. If the alert offers only **Move to Bin** and **Done**, select **Done**. Select **Move to Bin** instead if the source, filename, or checksum does not match the preview page. +4. Open the Apple menu, select **System Settings**, then select **Privacy & Security**. +5. Scroll down to **Security**. Confirm that the message names **RecordCove**, then select **Open Anyway**. +6. Authenticate with your Mac login password or Touch ID if macOS asks. +7. The warning appears again. After confirming the app name, source, filename, and checksum, select **Open**. +8. RecordCove should open. macOS saves this as an exception for this specific copy of the app. -Do not disable Gatekeeper and do not run a Terminal command to remove quarantine. +The **Open Anyway** button is available for about one hour after a blocked launch. If it is missing, try to open RecordCove once more and immediately return to **Privacy & Security**. If it still does not appear, or macOS says the app is damaged, stop and tell the maintainer. + +Do not disable Gatekeeper, lower **Allow applications from**, or use Terminal workarounds such as `xattr`, `spctl`, `sudo`, or removal of `com.apple.quarantine`. ## Microphone permission diff --git a/README.md b/README.md index 9cf4f73..7ee90e9 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ The tester portal is `https://preview.recordcove.com`. The exact archive is atta The Downloads page reads the public GitHub prerelease inventory and displays only releases at or below the manifest-pinned accepted preview. The newest displayed asset must match the manifest URL, byte size, and SHA-256 digest exactly. A newer staged GitHub prerelease is therefore not promoted before its manifest is accepted. The page remembers the last selected version only in that browser's local storage; no download history is uploaded. -The preview is not Apple-notarized and is not the public product launch. The portal must retain that warning and the standard Finder control-click **Open** instructions. It must never tell testers to disable Gatekeeper or run a quarantine-removal command. +The preview is not Apple-notarized and is not the public product launch. The portal must retain that warning and the current Gatekeeper recovery path: attempt one launch, choose **Done** if macOS offers only **Move to Bin** and **Done**, then use **System Settings**, **Privacy & Security**, **Open Anyway**, authentication, and the final **Open** confirmation. It must never tell testers to disable Gatekeeper, lower app-security settings, or use Terminal commands to remove quarantine. ## Current model scope diff --git a/site/install.html b/site/install.html index b4cfcdb..fe37b37 100644 --- a/site/install.html +++ b/site/install.html @@ -1,3 +1,3 @@ Install RecordCove preview -

Install RecordCove

These steps are written for someone who does not normally install preview software.

Before you start

You need an Apple silicon Mac, macOS 14 or later, about 1 GB of free disk space, and an internet connection.

This early preview is ad-hoc signed and is not Apple-notarized. Install it only if you trust Preston Core Systems Limited, downloaded it from preview.recordcove.com, and the filename and checksum match the page.

Download and unzip

  1. Open the Preview downloads page and choose a version.
  2. Wait for the download to finish.
  3. Open Finder and select Downloads in the left sidebar.
  4. Double-click the downloaded RecordCove ZIP. Your Mac creates a folder containing RecordCove.
  5. Drag RecordCove into the Applications folder in Finder.

First launch

  1. Open Applications in Finder.
  2. Hold the Control key while clicking RecordCove, then select Open.
  3. macOS explains that Apple cannot verify the developer. Select Open only if the file and checksum match the Downloads page.
  4. RecordCove should open. If macOS says the app is damaged, stop and tell the maintainer.

Do not disable Gatekeeper and do not run a Terminal command to remove quarantine.

Microphone permission

RecordCove asks for microphone permission only when it needs to record. Select Allow if you intend to record.

Updating later

Finish any active recording, quit RecordCove, open Preview downloads, choose the newer preview, and replace the app in Applications. Your local recording library is stored separately.

+

Install RecordCove

These steps are written for someone who does not normally install preview software.

Before you start

You need an Apple silicon Mac, macOS 14 or later, about 1 GB of free disk space, and an internet connection.

This early preview is ad-hoc signed and is not Apple-notarized. Install it only if you trust Preston Core Systems Limited, downloaded it from preview.recordcove.com, and the filename and checksum match the page.

Download and unzip

  1. Open the Preview downloads page and choose a version.
  2. Wait for the download to finish.
  3. Open Finder and select Downloads in the left sidebar.
  4. Double-click the downloaded RecordCove ZIP. Your Mac creates a folder containing RecordCove.
  5. Drag RecordCove into the Applications folder in Finder.

First launch

  1. Open Applications in Finder.
  2. Double-click RecordCove once. macOS may explain that Apple cannot verify the app is free of malware.
  3. If the alert offers only Move to Bin and Done, select Done. Select Move to Bin instead if the source, filename, or checksum does not match the Downloads page.
  4. Open the Apple menu, select System Settings, then select Privacy & Security.
  5. Scroll down to Security. Confirm that the message names RecordCove, then select Open Anyway.
  6. Authenticate with your Mac login password or Touch ID if macOS asks.
  7. The warning appears again. After confirming the app name, source, filename, and checksum, select Open.
  8. RecordCove should open. macOS saves this as an exception for this specific copy of the app.

The Open Anyway button is available for about one hour after a blocked launch. If it is missing, try to open RecordCove once more and immediately return to Privacy & Security. If it still does not appear, or macOS says the app is damaged, stop and tell the maintainer.

Do not disable Gatekeeper, lower Allow applications from, or use Terminal workarounds such as xattr, spctl, sudo, or removal of com.apple.quarantine.

Microphone permission

RecordCove asks for microphone permission only when it needs to record. Select Allow if you intend to record.

Updating later

Finish any active recording, quit RecordCove, open Preview downloads, choose the newer preview, and replace the app in Applications. Your local recording library is stored separately.

diff --git a/test/site.test.mjs b/test/site.test.mjs index b3e2377..db5af73 100644 --- a/test/site.test.mjs +++ b/test/site.test.mjs @@ -221,16 +221,31 @@ test("release updater rejects malformed identity and changed safety controls", a test("non-technical guides explain the ZIP and safe first launch", async () => { const install = await readFile("INSTALL.md", "utf8"); + const installPage = await readFile("site/install.html", "utf8"); const testing = await readFile("TESTING.md", "utf8"); assert.match(install, /Double-click `RecordCove-macOS-preview\.zip`/); - assert.match(install, /Hold the Control key/); + for (const guide of [install, installPage]) { + assert.match(guide, /Move to Bin/); + assert.match(guide, /Done/); + assert.match(guide, /System Settings/); + assert.match(guide, /Privacy & Security|Privacy & Security/); + assert.match(guide, /Open Anyway/); + assert.match(guide, /password or Touch ID/); + assert.match(guide, /select Open<\/strong>|select \*\*Open\*\*/); + assert.match(guide, /about one hour/); + assert.match(guide, /Do not disable Gatekeeper/); + assert.match(guide, /xattr/); + assert.match(guide, /spctl/); + assert.match(guide, /sudo/); + assert.match(guide, /com\.apple\.quarantine/); + } assert.match(testing, /simple first test/i); assert.match(testing, /Feedwish/); assert.match(testing, /without an account/); assert.match(testing, /private management code/); assert.doesNotMatch(`${install}\n${testing}`, /GitHub account/); - assert.match(install, /Do not disable Gatekeeper/); - assert.doesNotMatch(install, /quarantine-removal command/); + assert.doesNotMatch(`${install}\n${installPage}`, /disable Gatekeeper to continue/i); + assert.doesNotMatch(`${install}\n${installPage}`, /run (?:the )?(?:following )?command/i); }); test("downloads page exposes accepted preview history and browser-local update tracking", async () => { From a548c210cf197a39137323b4e0a834e4e00986d1 Mon Sep 17 00:00:00 2001 From: promisepreston Date: Sat, 15 Aug 2026 15:43:44 +0200 Subject: [PATCH 2/5] docs: explain bundled local models --- INSTALL.md | 6 ++++-- README.md | 3 +++ TESTING.md | 19 ++++++++++--------- site/index.html | 6 +++++- site/install.html | 2 +- site/testing.html | 2 +- test/site.test.mjs | 9 +++++++++ 7 files changed, 33 insertions(+), 14 deletions(-) diff --git a/INSTALL.md b/INSTALL.md index ec01009..1d38557 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -4,7 +4,9 @@ These steps are written for someone who does not normally install preview softwa ## Before you start -You need an Apple silicon Mac, macOS 14 or later, about 1 GB of free disk space, and an internet connection. RecordCove works locally and does not require a RecordCove account. +You need an Apple silicon Mac, macOS 14 or later, at least 6 GB of free disk space during installation, and an internet connection for the initial download. RecordCove works locally after installation and does not require a RecordCove account. + +The preview is a large download because it includes two verified local models: **Whisper Small English** for transcription and **IBM Granite 4.1 3B** for titles, summaries, and transcript enhancement. Both are installed with RecordCove. Granite is selected by default so a new tester can evaluate the intended local Understanding experience without a second model download. Apple on-device and Ministral remain optional choices in Models. This early preview is ad-hoc signed and is not Apple-notarized. Install it only if you trust Preston Core Systems Limited, downloaded it from `https://preview.recordcove.com`, and the filename and checksum match the preview page. @@ -12,7 +14,7 @@ This early preview is ad-hoc signed and is not Apple-notarized. Install it only 1. Open `https://preview.recordcove.com/downloads.html` in Safari, Chrome, or another browser. 2. Choose the newest accepted preview. The page shows its publication date and remembers the version selected in that browser so it can highlight a later update. -3. Wait for the download to finish. It is large because Whisper Small English is included. +3. Wait for the download to finish. The current bundled-model candidate is about 2.53 GB as a ZIP and about 2.5 GB after extraction. Keeping at least 6 GB free allows the ZIP and extracted application to exist together during installation. 4. Open Finder and select **Downloads** in the left sidebar. 5. Double-click `RecordCove-macOS-preview.zip`. Your Mac creates a folder containing `RecordCove.app`. 6. Drag **RecordCove** into the **Applications** folder in Finder. diff --git a/README.md b/README.md index 7ee90e9..d5ccbcd 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,8 @@ The Downloads page reads the public GitHub prerelease inventory and displays onl The preview is not Apple-notarized and is not the public product launch. The portal must retain that warning and the current Gatekeeper recovery path: attempt one launch, choose **Done** if macOS offers only **Move to Bin** and **Done**, then use **System Settings**, **Privacy & Security**, **Open Anyway**, authentication, and the final **Open** confirmation. It must never tell testers to disable Gatekeeper, lower app-security settings, or use Terminal commands to remove quarantine. +The next bundled-model preview includes verified Whisper Small English and IBM Granite 4.1 3B inside the application. Whisper is the default transcription model and Granite is the default Understanding model for titles, summaries, and enhancement. Testers must not need a second Granite download or be silently moved to Apple on-device. The measured owner-preview candidate is 2,528,517,655 bytes as a ZIP, so it cannot be uploaded as one GitHub Release asset. Publication remains blocked until a reviewed distribution channel can serve that exact large artifact without changing the package or safety contract. + ## Current model scope For this preview, RecordCove focuses model discovery, qualification, and packaging on model developers and originating model families from North America, Europe, and Africa. Models originating from mainland China are outside the current evaluation and packaging scope. @@ -25,6 +27,7 @@ This is a current release-scope and supply-chain qualification decision. It is n 7. Keep Developer ID signing, notarization, Homebrew, trusted CI, and public product launch outside this preview lane. 8. Use only privacy-safe product imagery with synthetic content. Public screenshots must never show a real recording, transcript, summary, prompt, model output, filename, path, category, tag, or other user data. 9. Version static CSS and image URLs when their bytes change so cached preview pages cannot combine new markup with stale presentation rules. +10. Explain that both default local models are included, why the archive is large, and that at least 6 GB of temporary free space is recommended for download plus extraction. Tester instructions are in [INSTALL.md](INSTALL.md) and [TESTING.md](TESTING.md). The distribution boundary is in [PRIVATE_PREVIEW_NOTICE.md](PRIVATE_PREVIEW_NOTICE.md). diff --git a/TESTING.md b/TESTING.md index 0bd13da..b90f486 100644 --- a/TESTING.md +++ b/TESTING.md @@ -8,19 +8,20 @@ The preview currently focuses model discovery and qualification on developers an 1. Open RecordCove. 2. Complete the four onboarding screens. -3. Confirm **Whisper Small English** is shown as included and verified. -4. Select **New Recording**. -5. Record about 20 seconds of ordinary, non-private speech. -6. Select **Stop and Save**. -7. Confirm the recording appears in **All Recordings** and does not say it was recovered after a normal save. -8. Play the recording. -9. Transcribe it with Whisper Small English. -10. Confirm the transcript covers the full recording. +3. Confirm **Whisper Small English** and **IBM Granite 4.1 3B** are both shown as included and verified. No second model download should be required. +4. Confirm Whisper Small English is selected for transcription and IBM Granite is selected for Understanding. +5. Select **New Recording**. +6. Record about 20 seconds of ordinary, non-private speech. +7. Select **Stop and Save**. +8. Confirm the recording appears in **All Recordings** and does not say it was recovered after a normal save. +9. Play the recording and transcribe it with Whisper Small English. +10. Generate a title and summary, then try **Enhance**. Confirm the local results complete without switching to Apple on-device unless you explicitly selected Apple yourself. +11. Confirm the transcript covers the full recording. ## Everyday feature checks - Copy the transcript and confirm the button changes back from **Copied** to **Copy** after a short moment. -- Generate a Summary with an installed Understanding model. +- Regenerate a Summary with IBM Granite selected. - Try **Enhance** and confirm the original transcript remains available in Version History. - Try **Clean up** and confirm the original transcript remains available. - Create a Quick Note, type a title, press Return, and confirm the cursor moves into the note body. diff --git a/site/index.html b/site/index.html index b7c5c46..574cc8b 100644 --- a/site/index.html +++ b/site/index.html @@ -57,7 +57,11 @@

Protect your private content

Feedwish accepts feedback without an account and gives you a private management code for status checks or permanent withdrawal. Signing in is optional and is only needed to follow feedback.

-

Current model scope

+

Two local models are included

+

Whisper Small English is included and selected for transcription. IBM Granite 4.1 3B is included and selected for titles, summaries, and transcript enhancement.

+

Including both verified models makes the download much larger, but it lets testers use RecordCove's intended local defaults without downloading another model after installation. Apple on-device and Ministral remain optional choices.

+

The bundled-model owner-preview candidate measures about 2.53 GB as a ZIP. Its download will remain unavailable until the exact large artifact has an approved and verified distribution path.

+

Current qualification scope

For this preview, RecordCove focuses model discovery and qualification on developers and originating model families from North America, Europe, and Africa.

Models originating from mainland China are outside the current evaluation and packaging scope. This is a release-scope decision, not a claim that included models are universally better or that developer region proves local privacy.

diff --git a/site/install.html b/site/install.html index fe37b37..3492e84 100644 --- a/site/install.html +++ b/site/install.html @@ -1,3 +1,3 @@ Install RecordCove preview -

Install RecordCove

These steps are written for someone who does not normally install preview software.

Before you start

You need an Apple silicon Mac, macOS 14 or later, about 1 GB of free disk space, and an internet connection.

This early preview is ad-hoc signed and is not Apple-notarized. Install it only if you trust Preston Core Systems Limited, downloaded it from preview.recordcove.com, and the filename and checksum match the page.

Download and unzip

  1. Open the Preview downloads page and choose a version.
  2. Wait for the download to finish.
  3. Open Finder and select Downloads in the left sidebar.
  4. Double-click the downloaded RecordCove ZIP. Your Mac creates a folder containing RecordCove.
  5. Drag RecordCove into the Applications folder in Finder.

First launch

  1. Open Applications in Finder.
  2. Double-click RecordCove once. macOS may explain that Apple cannot verify the app is free of malware.
  3. If the alert offers only Move to Bin and Done, select Done. Select Move to Bin instead if the source, filename, or checksum does not match the Downloads page.
  4. Open the Apple menu, select System Settings, then select Privacy & Security.
  5. Scroll down to Security. Confirm that the message names RecordCove, then select Open Anyway.
  6. Authenticate with your Mac login password or Touch ID if macOS asks.
  7. The warning appears again. After confirming the app name, source, filename, and checksum, select Open.
  8. RecordCove should open. macOS saves this as an exception for this specific copy of the app.

The Open Anyway button is available for about one hour after a blocked launch. If it is missing, try to open RecordCove once more and immediately return to Privacy & Security. If it still does not appear, or macOS says the app is damaged, stop and tell the maintainer.

Do not disable Gatekeeper, lower Allow applications from, or use Terminal workarounds such as xattr, spctl, sudo, or removal of com.apple.quarantine.

Microphone permission

RecordCove asks for microphone permission only when it needs to record. Select Allow if you intend to record.

Updating later

Finish any active recording, quit RecordCove, open Preview downloads, choose the newer preview, and replace the app in Applications. Your local recording library is stored separately.

Copyright Preston Core Systems Limited.
+

Install RecordCove

These steps are written for someone who does not normally install preview software.

Before you start

You need an Apple silicon Mac, macOS 14 or later, at least 6 GB of free disk space during installation, and an internet connection for the initial download.

RecordCove includes verified Whisper Small English for transcription and IBM Granite 4.1 3B for titles, summaries, and transcript enhancement. Both are installed with the app, and Granite is the default Understanding model. The bundled-model candidate is about 2.53 GB as a ZIP and about 2.5 GB after extraction; the extra free space lets both copies exist during installation.

This early preview is ad-hoc signed and is not Apple-notarized. Install it only if you trust Preston Core Systems Limited, downloaded it from preview.recordcove.com, and the filename and checksum match the page.

Download and unzip

  1. Open the Preview downloads page and choose a version.
  2. Wait for the large bundled-model download to finish.
  3. Open Finder and select Downloads in the left sidebar.
  4. Double-click the downloaded RecordCove ZIP. Your Mac creates a folder containing RecordCove.
  5. Drag RecordCove into the Applications folder in Finder.

First launch

  1. Open Applications in Finder.
  2. Double-click RecordCove once. macOS may explain that Apple cannot verify the app is free of malware.
  3. If the alert offers only Move to Bin and Done, select Done. Select Move to Bin instead if the source, filename, or checksum does not match the Downloads page.
  4. Open the Apple menu, select System Settings, then select Privacy & Security.
  5. Scroll down to Security. Confirm that the message names RecordCove, then select Open Anyway.
  6. Authenticate with your Mac login password or Touch ID if macOS asks.
  7. The warning appears again. After confirming the app name, source, filename, and checksum, select Open.
  8. RecordCove should open. macOS saves this as an exception for this specific copy of the app.

The Open Anyway button is available for about one hour after a blocked launch. If it is missing, try to open RecordCove once more and immediately return to Privacy & Security. If it still does not appear, or macOS says the app is damaged, stop and tell the maintainer.

Do not disable Gatekeeper, lower Allow applications from, or use Terminal workarounds such as xattr, spctl, sudo, or removal of com.apple.quarantine.

Microphone permission

RecordCove asks for microphone permission only when it needs to record. Select Allow if you intend to record.

Updating later

Finish any active recording, quit RecordCove, open Preview downloads, choose the newer preview, and replace the app in Applications. Your local recording library is stored separately.

Copyright Preston Core Systems Limited.
diff --git a/site/testing.html b/site/testing.html index 2a2ee52..ff29d50 100644 --- a/site/testing.html +++ b/site/testing.html @@ -1,3 +1,3 @@ Test RecordCove preview -

Test RecordCove

Use only recordings you are legally allowed to make. You never need to share the recording or its written content.

A simple first test

  1. Complete onboarding and confirm Whisper Small English is included and verified.
  2. Make a short, non-private recording.
  3. Select Stop and Save.
  4. Confirm it appears in All Recordings without a recovery or review pop-up.
  5. Play it, transcribe it, and confirm the transcript covers the full recording.

Everyday checks

  • Confirm Copy changes back after a short moment.
  • Generate a Summary with an installed Understanding model.
  • Try Enhance and Clean up, then confirm the original remains in Version History.
  • Create a Quick Note, type a title, press Return, and confirm the cursor moves to the body.
  • Move an item to Recently Deleted, restore it, and confirm the 30-day notice.

Long recording test

If you have a long recording you are allowed to use, let RecordCove transcribe it without interruption. Check the beginning, middle, and end. Confirm processing boundaries do not cut off words, omit sections, repeat passages, or introduce unrelated paragraph breaks.

Report useful feedback

Select Feedback in RecordCove, or open the RecordCove Feedwish board. You can submit without an account and may add a display name if you want. Save the private management code shown after submission; it lets you check or permanently withdraw that feedback later. Signing in is optional and is only needed to follow feedback.

Include your macOS version, Mac type, RecordCove version and revision, selected model, screen, action, expected behavior, and high-level result.

Never send audio, transcripts, summaries, prompts, model output, tokens, credentials, personal filenames, or full file paths.

Copyright Preston Core Systems Limited.
+

Test RecordCove

Use only recordings you are legally allowed to make. You never need to share the recording or its written content.

A simple first test

  1. Complete onboarding and confirm Whisper Small English and IBM Granite 4.1 3B are both included and verified.
  2. Confirm Whisper Small English is selected for transcription and IBM Granite is selected for Understanding. No second model download should be required.
  3. Make a short, non-private recording.
  4. Select Stop and Save.
  5. Confirm it appears in All Recordings without a recovery or review pop-up.
  6. Play it, transcribe it, generate a title and summary, and try Enhance. Confirm each local result completes without switching to Apple on-device unless you chose Apple yourself.

Everyday checks

  • Confirm Copy changes back after a short moment.
  • Regenerate a Summary with IBM Granite selected.
  • Try Enhance and Clean up, then confirm the original remains in Version History.
  • Create a Quick Note, type a title, press Return, and confirm the cursor moves to the body.
  • Move an item to Recently Deleted, restore it, and confirm the 30-day notice.

Long recording test

If you have a long recording you are allowed to use, let RecordCove transcribe it without interruption. Check the beginning, middle, and end. Confirm processing boundaries do not cut off words, omit sections, repeat passages, or introduce unrelated paragraph breaks.

Report useful feedback

Select Feedback in RecordCove, or open the RecordCove Feedwish board. You can submit without an account and may add a display name if you want. Save the private management code shown after submission; it lets you check or permanently withdraw that feedback later. Signing in is optional and is only needed to follow feedback.

Include your macOS version, Mac type, RecordCove version and revision, selected model, screen, action, expected behavior, and high-level result.

Never send audio, transcripts, summaries, prompts, model output, tokens, credentials, personal filenames, or full file paths.

Copyright Preston Core Systems Limited.
diff --git a/test/site.test.mjs b/test/site.test.mjs index db5af73..d664fa5 100644 --- a/test/site.test.mjs +++ b/test/site.test.mjs @@ -43,6 +43,10 @@ test("preview page carries the exact public preview package and safety boundary" assert.match(page, /North America, Europe, and Africa/); assert.match(page, /mainland China are outside the current evaluation and packaging scope/); assert.match(page, /not a claim that included models are universally better/); + assert.match(page, /Whisper Small English/); + assert.match(page, /IBM Granite 4\.1 3B/); + assert.match(page, /about 2\.53 GB as a ZIP/); + assert.match(page, /download will remain unavailable/); assert.doesNotMatch(page, /KeepVox/); assert.match(page, new RegExp(manifest.sha256)); assert.match(manifest.sourceRevision, /^[0-9a-f]{40}$/); @@ -225,6 +229,10 @@ test("non-technical guides explain the ZIP and safe first launch", async () => { const testing = await readFile("TESTING.md", "utf8"); assert.match(install, /Double-click `RecordCove-macOS-preview\.zip`/); for (const guide of [install, installPage]) { + assert.match(guide, /at least 6 GB/); + assert.match(guide, /Whisper Small English/); + assert.match(guide, /IBM Granite 4\.1 3B/); + assert.match(guide, /2\.53 GB/); assert.match(guide, /Move to Bin/); assert.match(guide, /Done/); assert.match(guide, /System Settings/); @@ -240,6 +248,7 @@ test("non-technical guides explain the ZIP and safe first launch", async () => { assert.match(guide, /com\.apple\.quarantine/); } assert.match(testing, /simple first test/i); + assert.match(await readFile("site/testing.html", "utf8"), /No second model download should be required/); assert.match(testing, /Feedwish/); assert.match(testing, /without an account/); assert.match(testing, /private management code/); From d851bb3e73e377d00fbe83c4bf9ad9eefc4b9bc9 Mon Sep 17 00:00:00 2001 From: promisepreston Date: Sat, 15 Aug 2026 16:08:18 +0200 Subject: [PATCH 3/5] docs: select reserved r2 preview channel --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d5ccbcd..c6a5718 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ The Downloads page reads the public GitHub prerelease inventory and displays onl The preview is not Apple-notarized and is not the public product launch. The portal must retain that warning and the current Gatekeeper recovery path: attempt one launch, choose **Done** if macOS offers only **Move to Bin** and **Done**, then use **System Settings**, **Privacy & Security**, **Open Anyway**, authentication, and the final **Open** confirmation. It must never tell testers to disable Gatekeeper, lower app-security settings, or use Terminal commands to remove quarantine. -The next bundled-model preview includes verified Whisper Small English and IBM Granite 4.1 3B inside the application. Whisper is the default transcription model and Granite is the default Understanding model for titles, summaries, and enhancement. Testers must not need a second Granite download or be silently moved to Apple on-device. The measured owner-preview candidate is 2,528,517,655 bytes as a ZIP, so it cannot be uploaded as one GitHub Release asset. Publication remains blocked until a reviewed distribution channel can serve that exact large artifact without changing the package or safety contract. +The next bundled-model preview includes verified Whisper Small English and IBM Granite 4.1 3B inside the application. Whisper is the default transcription model and Granite is the default Understanding model for titles, summaries, and enhancement. Testers must not need a second Granite download or be silently moved to Apple on-device. The exact owner-preview candidate is 2,528,517,650 bytes as a ZIP, so it cannot be uploaded as one GitHub Release asset. The reserved `recordcove-preview-downloads` R2 bucket and `downloads.preview.recordcove.com` domain are the capacity-fit design, but publication remains blocked until a reviewed multipart publisher uploads and independently verifies the exact object before the manifest is activated. ## Current model scope From 26920a4d2aa91aa5ea39e2897c1646d81eaefd75 Mon Sep 17 00:00:00 2001 From: promisepreston Date: Sat, 15 Aug 2026 16:29:35 +0200 Subject: [PATCH 4/5] feat: support immutable preview downloads --- README.md | 8 ++++---- scripts/update-release.mjs | 16 +++++++++++----- site/downloads.html | 2 +- site/downloads.mjs | 39 ++++++++++++++++++++++++++++++++++---- test/site.test.mjs | 27 +++++++++++++++++++++++++- 5 files changed, 77 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index c6a5718..830fcc6 100644 --- a/README.md +++ b/README.md @@ -2,13 +2,13 @@ This public, preview-only repository controls the RecordCove pre-release portal, release manifest, public prerelease archive, and non-technical tester guidance. Product source code, recordings, transcripts, model files, tester data, and credentials are not stored here. -The tester portal is `https://preview.recordcove.com`. The exact archive is attached to the manifest-pinned public GitHub prerelease after its revision, byte size, SHA-256 checksum, bundle identity, and ad-hoc signature are verified. Testers do not need a GitHub account to download a public release asset. +The tester portal is `https://preview.recordcove.com`. The exact archive is linked by the manifest-pinned public GitHub prerelease after its revision, byte size, SHA-256 checksum, bundle identity, and ad-hoc signature are verified. Current large bundled-model archives use the immutable `downloads.preview.recordcove.com` object path; earlier accepted previews may remain GitHub-hosted. Testers do not need a GitHub account. -The Downloads page reads the public GitHub prerelease inventory and displays only releases at or below the manifest-pinned accepted preview. The newest displayed asset must match the manifest URL, byte size, and SHA-256 digest exactly. A newer staged GitHub prerelease is therefore not promoted before its manifest is accepted. The page remembers the last selected version only in that browser's local storage; no download history is uploaded. +The Downloads page reads the public GitHub prerelease inventory and displays only releases at or below the manifest-pinned accepted preview. The newest metadata-only release must name the same immutable download URL that the manifest binds to the exact byte size and SHA-256 digest. Historical GitHub assets retain their provider digest checks. A newer staged prerelease is therefore not promoted before its manifest is accepted. The page remembers the last selected version only in that browser's local storage; no download history is uploaded. The preview is not Apple-notarized and is not the public product launch. The portal must retain that warning and the current Gatekeeper recovery path: attempt one launch, choose **Done** if macOS offers only **Move to Bin** and **Done**, then use **System Settings**, **Privacy & Security**, **Open Anyway**, authentication, and the final **Open** confirmation. It must never tell testers to disable Gatekeeper, lower app-security settings, or use Terminal commands to remove quarantine. -The next bundled-model preview includes verified Whisper Small English and IBM Granite 4.1 3B inside the application. Whisper is the default transcription model and Granite is the default Understanding model for titles, summaries, and enhancement. Testers must not need a second Granite download or be silently moved to Apple on-device. The exact owner-preview candidate is 2,528,517,650 bytes as a ZIP, so it cannot be uploaded as one GitHub Release asset. The reserved `recordcove-preview-downloads` R2 bucket and `downloads.preview.recordcove.com` domain are the capacity-fit design, but publication remains blocked until a reviewed multipart publisher uploads and independently verifies the exact object before the manifest is activated. +The next bundled-model preview includes verified Whisper Small English and IBM Granite 4.1 3B inside the application. Whisper is the default transcription model and Granite is the default Understanding model for titles, summaries, and enhancement. Testers must not need a second Granite download or be silently moved to Apple on-device. The exact owner-preview candidate is 2,528,517,650 bytes as a ZIP, so it cannot be uploaded as one GitHub Release asset. The protected publisher uses multipart staging in `recordcove-preview-downloads`, verifies the staged bytes, conditionally promotes an unused immutable key, verifies the final object, and then hashes the complete public response from `downloads.preview.recordcove.com` before staging the manifest. Provider credentials never enter the M3 build runner. ## Current model scope @@ -22,7 +22,7 @@ This is a current release-scope and supply-chain qualification decision. It is n 2. Match the portal manifest to the archive filename, byte size, and SHA-256 checksum. 3. Keep the product repository and all user content out of this preview-only repository. 4. Deploy the static portal only to the Terraform-managed Pages project. -5. Upload the exact archive only to the manifest-pinned public prerelease. +5. Upload the exact archive only through the protected immutable R2 publisher and keep the GitHub prerelease metadata-only for the bundled-model lane. 6. Verify the portal, download, checksum, extraction, and first-launch guide from an independent browser session. 7. Keep Developer ID signing, notarization, Homebrew, trusted CI, and public product launch outside this preview lane. 8. Use only privacy-safe product imagery with synthetic content. Public screenshots must never show a real recording, transcript, summary, prompt, model output, filename, path, category, tag, or other user data. diff --git a/scripts/update-release.mjs b/scripts/update-release.mjs index 8421aac..ac23b48 100644 --- a/scripts/update-release.mjs +++ b/scripts/update-release.mjs @@ -6,9 +6,11 @@ import { fileURLToPath } from "node:url"; const RELEASE_FILE = "RecordCove-macOS-preview.zip"; const RELEASE_REPOSITORY = "PrestonCoreSystems/recordcove-preview"; -const TAG_PATTERN = /^v(\d+\.\d+\.\d+)-preview\.(\d+)$/; +const RELEASE_ORIGIN = "https://downloads.preview.recordcove.com"; +const TAG_PATTERN = /^v(\d+\.\d+\.\d+)-preview\.([1-9]\d*)$/; const SHA_PATTERN = /^[0-9a-f]{40}$/; const DIGEST_PATTERN = /^[0-9a-f]{64}$/; +const MAXIMUM_ARCHIVE_BYTES = 4 * 1024 * 1024 * 1024; function requireValue(value, label, pattern) { if (!pattern.test(value)) { @@ -42,17 +44,21 @@ async function openRegularFileNoFollow(filePath, expectedParent) { export function validateReleaseManifest(manifest) { const tagMatch = TAG_PATTERN.exec(manifest.releaseTag ?? ""); - const currentDownloadUrl = `https://github.com/${RELEASE_REPOSITORY}/releases/download/${manifest.releaseTag}/${RELEASE_FILE}`; + const acceptedDownloadUrls = new Set([ + `https://github.com/${RELEASE_REPOSITORY}/releases/download/${manifest.releaseTag}/${RELEASE_FILE}`, + `${RELEASE_ORIGIN}/previews/${manifest.releaseTag}/${RELEASE_FILE}`, + ]); if ( !tagMatch || manifest.product !== "RecordCove" || manifest.version !== tagMatch[1] || manifest.file !== RELEASE_FILE || - manifest.downloadUrl !== currentDownloadUrl || + !acceptedDownloadUrls.has(manifest.downloadUrl) || !SHA_PATTERN.test(manifest.sourceRevision ?? "") || !DIGEST_PATTERN.test(manifest.sha256 ?? "") || !Number.isSafeInteger(manifest.bytes) || manifest.bytes <= 0 || + manifest.bytes > MAXIMUM_ARCHIVE_BYTES || manifest.signing !== "ad-hoc" || manifest.notarized !== false || manifest.publicReleaseApproved !== false || @@ -77,7 +83,7 @@ export async function updateRelease({ requireValue(archiveSha256, "archive SHA-256", DIGEST_PATTERN); const bytes = Number(archiveBytes); - if (!Number.isSafeInteger(bytes) || bytes <= 0) { + if (!Number.isSafeInteger(bytes) || bytes <= 0 || bytes > MAXIMUM_ARCHIVE_BYTES) { throw new Error("archive byte size is invalid"); } @@ -108,7 +114,7 @@ export async function updateRelease({ ) { throw new Error("release tag must be the next preview for the current version"); } - const downloadUrl = `https://github.com/${RELEASE_REPOSITORY}/releases/download/${releaseTag}/${RELEASE_FILE}`; + const downloadUrl = `${RELEASE_ORIGIN}/previews/${releaseTag}/${RELEASE_FILE}`; manifest.version = nextTagMatch[1]; manifest.releaseTag = releaseTag; manifest.bytes = bytes; diff --git a/site/downloads.html b/site/downloads.html index 8ae9f9a..cf25329 100644 --- a/site/downloads.html +++ b/site/downloads.html @@ -42,7 +42,7 @@

Previous previews

How version tracking works

The marker is stored only in this browser when you select a download. It is not an account, it is not uploaded, and it cannot confirm that the download or installation finished.

-

GitHub currently serves the verified archive as RecordCove-macOS-preview.zip. The Downloads page records the exact preview version beside it; the installed app remains named RecordCove.

+

New bundled-model archives are served from the immutable RecordCove Preview download domain, while GitHub keeps the dated release notes. Earlier verified GitHub-hosted previews remain available in the same history. The installed app remains named RecordCove.

Copyright Preston Core Systems Limited. RecordCove preview.
diff --git a/site/downloads.mjs b/site/downloads.mjs index 5eac832..23d2859 100644 --- a/site/downloads.mjs +++ b/site/downloads.mjs @@ -1,5 +1,6 @@ const RELEASE_API = "https://api.github.com/repos/PrestonCoreSystems/recordcove-preview/releases"; const RELEASE_REPOSITORY = "PrestonCoreSystems/recordcove-preview"; +const RELEASE_ORIGIN = "https://downloads.preview.recordcove.com"; const RELEASE_FILE = "RecordCove-macOS-preview.zip"; const RELEASE_PAGE_SIZE = 100; const MAX_RELEASE_PAGES = 20; @@ -26,25 +27,52 @@ export function compareReleaseTags(left, right) { return 0; } -export function normalizeRelease(release) { +export function normalizeRelease(release, manifest = null) { const parts = releaseParts(release?.tag_name); if (!parts || release.draft !== false || release.prerelease !== true) { return null; } const expectedReleaseUrl = `https://github.com/${RELEASE_REPOSITORY}/releases/tag/${release.tag_name}`; const expectedDownloadUrl = `https://github.com/${RELEASE_REPOSITORY}/releases/download/${release.tag_name}/${RELEASE_FILE}`; + const expectedR2DownloadUrl = `${RELEASE_ORIGIN}/previews/${release.tag_name}/${RELEASE_FILE}`; const asset = release.assets?.find((candidate) => candidate.name === RELEASE_FILE); const digestMatch = DIGEST.exec(asset?.digest ?? ""); const publishedAt = new Date(release.published_at ?? ""); if ( release.html_url !== expectedReleaseUrl || + Number.isNaN(publishedAt.getTime()) + ) { + return null; + } + if ( + manifest?.releaseTag === release.tag_name && + manifest.downloadUrl === expectedR2DownloadUrl + ) { + if ( + !Array.isArray(release.assets) || + release.assets.length !== 0 || + !String(release.body ?? "").includes(`Verified download: ${expectedR2DownloadUrl}`) + ) { + return null; + } + return { + tag: release.tag_name, + version: `${parts[0]}.${parts[1]}.${parts[2]}`, + previewNumber: parts[3], + publishedAt: publishedAt.toISOString(), + releaseUrl: release.html_url, + downloadUrl: manifest.downloadUrl, + bytes: manifest.bytes, + sha256: manifest.sha256, + }; + } + if ( !asset || asset.state !== "uploaded" || asset.browser_download_url !== expectedDownloadUrl || !Number.isSafeInteger(asset.size) || asset.size <= 0 || - !digestMatch || - Number.isNaN(publishedAt.getTime()) + !digestMatch ) { return null; } @@ -62,7 +90,7 @@ export function normalizeRelease(release) { export function acceptedReleases(rawReleases, manifest) { const releases = rawReleases - .map(normalizeRelease) + .map((release) => normalizeRelease(release, manifest)) .filter(Boolean) .filter((release) => compareReleaseTags(release.tag, manifest.releaseTag) <= 0) .sort((left, right) => compareReleaseTags(right.tag, left.tag)); @@ -165,6 +193,9 @@ function formatDate(value) { } function formatBytes(bytes) { + if (bytes >= 1_000_000_000) { + return `${(bytes / 1_000_000_000).toFixed(2)} GB`; + } return `${(bytes / 1_000_000).toFixed(1)} MB`; } diff --git a/test/site.test.mjs b/test/site.test.mjs index d664fa5..308b35c 100644 --- a/test/site.test.mjs +++ b/test/site.test.mjs @@ -80,6 +80,10 @@ test("release updater changes only the next exact preview identity", async () => assert.equal(manifest.sourceRevision, requested.sourceRevision); assert.equal(manifest.sha256, requested.archiveSha256); assert.equal(manifest.bytes, Number(requested.archiveBytes)); + assert.equal( + manifest.downloadUrl, + `https://downloads.preview.recordcove.com/previews/${requested.releaseTag}/RecordCove-macOS-preview.zip`, + ); assert.match(page, new RegExp(requested.releaseTag)); assert.match(page, new RegExp(requested.sourceRevision)); assert.match(page, new RegExp(requested.archiveSha256)); @@ -297,7 +301,7 @@ test("overview shows a privacy-safe local app preview", async () => { assert.doesNotMatch(image, /KeepVox/); }); -test("release catalog accepts only manifest-bounded exact GitHub assets", async () => { +test("release catalog accepts exact historical assets and manifest-bounded R2 metadata", async () => { const manifest = JSON.parse(await readFile("site/release-manifest.json", "utf8")); const release = (tag, overrides = {}) => ({ tag_name: tag, @@ -306,6 +310,7 @@ test("release catalog accepts only manifest-bounded exact GitHub assets", async prerelease: true, published_at: "2026-08-15T07:55:59Z", html_url: `https://github.com/PrestonCoreSystems/recordcove-preview/releases/tag/${tag}`, + body: "", assets: [ { name: "RecordCove-macOS-preview.zip", @@ -341,6 +346,26 @@ test("release catalog accepts only manifest-bounded exact GitHub assets", async acceptedReleases([future, previous, invalid, current], manifest).map(({ tag }) => tag), [manifest.releaseTag, previousTag], ); + + const r2Tag = "v0.1.0-preview.9"; + const r2DownloadUrl = `https://downloads.preview.recordcove.com/previews/${r2Tag}/RecordCove-macOS-preview.zip`; + const r2Manifest = { + ...manifest, + releaseTag: r2Tag, + downloadUrl: r2DownloadUrl, + bytes: 2528517650, + sha256: "a".repeat(64), + }; + const r2Current = release(r2Tag, { + assets: [], + body: `Verified download: ${r2DownloadUrl}`, + }); + assert.deepEqual( + acceptedReleases([r2Current, current, previous], r2Manifest).map(({ tag }) => tag), + [r2Tag, manifest.releaseTag, previousTag], + ); + assert.equal(normalizeRelease({ ...r2Current, body: "" }, r2Manifest), null); + assert.equal(normalizeRelease({ ...r2Current, assets: current.assets }, r2Manifest), null); }); test("download state distinguishes current and newer accepted previews", () => { From 9db31fa4b15730e0506c77a14017a7e9b57984b3 Mon Sep 17 00:00:00 2001 From: promisepreston Date: Sat, 15 Aug 2026 18:58:07 +0200 Subject: [PATCH 5/5] docs: derive preview package size from manifest --- README.md | 2 +- test/site.test.mjs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 830fcc6..74fd4fa 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ The Downloads page reads the public GitHub prerelease inventory and displays onl The preview is not Apple-notarized and is not the public product launch. The portal must retain that warning and the current Gatekeeper recovery path: attempt one launch, choose **Done** if macOS offers only **Move to Bin** and **Done**, then use **System Settings**, **Privacy & Security**, **Open Anyway**, authentication, and the final **Open** confirmation. It must never tell testers to disable Gatekeeper, lower app-security settings, or use Terminal commands to remove quarantine. -The next bundled-model preview includes verified Whisper Small English and IBM Granite 4.1 3B inside the application. Whisper is the default transcription model and Granite is the default Understanding model for titles, summaries, and enhancement. Testers must not need a second Granite download or be silently moved to Apple on-device. The exact owner-preview candidate is 2,528,517,650 bytes as a ZIP, so it cannot be uploaded as one GitHub Release asset. The protected publisher uses multipart staging in `recordcove-preview-downloads`, verifies the staged bytes, conditionally promotes an unused immutable key, verifies the final object, and then hashes the complete public response from `downloads.preview.recordcove.com` before staging the manifest. Provider credentials never enter the M3 build runner. +The next bundled-model preview includes verified Whisper Small English and IBM Granite 4.1 3B inside the application. Whisper is the default transcription model and Granite is the default Understanding model for titles, summaries, and enhancement. Testers must not need a second Granite download or be silently moved to Apple on-device. The bundled-model archive exceeds GitHub Release's single-asset limit. Its exact accepted byte count and SHA-256 checksum must come only from the immutable release manifest generated from the final verified package, never from a hand-maintained README value. The protected publisher uses multipart staging in `recordcove-preview-downloads`, verifies the staged bytes, conditionally promotes an unused immutable key, verifies the final object, and then hashes the complete public response from `downloads.preview.recordcove.com` before staging the manifest. Provider credentials never enter the M3 build runner. ## Current model scope diff --git a/test/site.test.mjs b/test/site.test.mjs index 308b35c..ac0cf2e 100644 --- a/test/site.test.mjs +++ b/test/site.test.mjs @@ -353,7 +353,7 @@ test("release catalog accepts exact historical assets and manifest-bounded R2 me ...manifest, releaseTag: r2Tag, downloadUrl: r2DownloadUrl, - bytes: 2528517650, + bytes: 2600000000, sha256: "a".repeat(64), }; const r2Current = release(r2Tag, {