Replace Cohere CoreML backend with pinned transcribe.cpp - #865
Replace Cohere CoreML backend with pinned transcribe.cpp#865dudemeister23 wants to merge 3 commits into
Conversation
## What Changed - Preserve the Cohere engine identity and product contracts while routing native execution through a small actor-owned transcribe.cpp adapter. - Add revision-scoped Q5_K_M model download, exact size and SHA-256 verification, resumable recovery, bounded long-audio chunking, cancellation, and deterministic context teardown. - Pin upstream v0.1.3, the owned fork commit, wrapper version, immutable arm64 XCFramework release and checksum, and compatible model revision. Release scripts fail closed on pin, architecture, provenance, artifact-tree, or notice drift. - Keep automatic multilingual behavior local by invoking native transcription without a language hint and classifying returned text with Apple Natural Language for metadata. - Extend focused scheduler, lifecycle, CLI, persistence, unavailable-runtime, and stitching tests, and record English, German, Japanese, and Chinese runtime evidence. - Update ADR-029, the governing STT specifications, benchmark records, CLI documentation, distribution steps, and MIT and Apache-2.0 notices. ## Root Intent Replace the old FluidAudio/CoreML Cohere implementation without introducing a new user-facing engine or disturbing the surrounding MacParakeet capture, persistence, scheduler, and CLI behavior. The shipping boundary must be reproducible, local-only, cancellation-safe, and owned by MacParakeet rather than a floating upstream binary. ## Seed Prompt Replace only Cohere Transcribe execution with handy-computer/transcribe.cpp v0.1.3 through an owned, self-built macOS arm64 XCFramework. Preserve every existing Cohere product contract, verify a pinned Q5_K_M model, handle long audio safely, retain local-only privacy, and document exact source, artifact, model, license, benchmark, and distribution evidence. Do not broaden the change into unrelated STT cleanup. ## ADRs Applied - ADR-016: centralized STT runtime, scheduler admission, and meeting leases. - ADR-026: Cohere remains the narrow additional-runtime exception, not another engine family. - ADR-029: transcribe.cpp adapter boundary, lifecycle, multilingual behavior, supply-chain pins, and release evidence. ## Author Notes The native Cohere runtime transcribes all fourteen official languages without caller hints but has no language-identification head. Transcript language metadata is therefore best-effort local classification and can be absent for short or ambiguous text. No live preview or word timings are synthesized. The representative multilingual runtime pass is complete; full-corpus accuracy remains the historical CoreML baseline until separately rerun on Q5_K_M.
|
Caution The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased. |
📝 WalkthroughWalkthroughCohere’s speech engine now uses a pinned transcribe.cpp backend with Metal/CPU execution, automatic language detection, verified GGUF model downloads, lifecycle-safe model deletion, updated CLI/UI behavior, expanded tests, benchmarks, and release documentation. ChangesCohere transcribe.cpp migration
Estimated code review effort: 4 (Complex) | ~60 minutes Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
Caution The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased. |
Greptile SummaryReplaces Cohere’s CoreML implementation with a pinned, arm64-only transcribe.cpp backend.
Confidence Score: 5/5The PR appears safe to merge with respect to the previously reported universal-build issue. No blocking failure remains in the reviewed fix. Files Needing Attention: No files require additional attention.
What T-Rex did
|
| Filename | Overview |
|---|---|
| Package.swift | Conditionally integrates the local TranscribeCpp package and compile flag; the previously reported universal-build conflict is addressed by the distribution guards. |
| scripts/dist/build_app_bundle.sh | Rejects universal builds using the arm64-only dependency and verifies, embeds, and validates the native framework for production bundles. |
| scripts/dist/verify_transcribe_cpp_release.sh | Fails closed on mismatched source, artifact, architecture, provenance, and license pins. |
| Sources/MacParakeetCore/STT/CohereTranscribeCppBackend.swift | Introduces the actor-owned native model and transcription-session boundary. |
| Sources/MacParakeetCore/STT/CohereTranscribeEngine.swift | Migrates Cohere transcription to the verified native backend while retaining its existing product contract. |
Reviews (2): Last reviewed commit: "Address Cohere backend review findings" | Re-trigger Greptile
There was a problem hiding this comment.
Actionable comments posted: 9
🧹 Nitpick comments (2)
Tests/MacParakeetTests/STT/CohereTranscribeEngineTests.swift (1)
846-856: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winBound the spin waiters with a deadline.
waitUntilLoadStarted/waitUntilTranscriptionStartedyield indefinitely. If a regression means the backend is never entered, these hang until the global XCTest timeout instead of failing fast with a useful message.♻️ Deadline-bounded waiters
- func waitUntilLoadStarted() async { - while !loadStarted { - await Task.yield() - } - } - - func waitUntilTranscriptionStarted() async { - while !transcriptionStarted { - await Task.yield() - } - } + func waitUntilLoadStarted() async throws { + try await wait(until: { self.loadStarted }) + } + + func waitUntilTranscriptionStarted() async throws { + try await wait(until: { self.transcriptionStarted }) + } + + private func wait( + until condition: () -> Bool, + timeout: Duration = .seconds(2) + ) async throws { + let deadline = ContinuousClock().now.advanced(by: timeout) + while !condition() { + guard ContinuousClock().now < deadline else { + throw MockBackendError.timedOut + } + try await Task.sleep(for: .milliseconds(1)) + } + }Note this changes the call sites at Lines 479 and 507 to
try await.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@Tests/MacParakeetTests/STT/CohereTranscribeEngineTests.swift` around lines 846 - 856, Update waitUntilLoadStarted and waitUntilTranscriptionStarted to use deadline-bounded waiting that throws a clear failure when their flags are not set in time, rather than yielding indefinitely. Mark both methods as throwing and update their call sites around the affected tests to use try await, preserving successful completion when the corresponding state is reached.Package.swift (1)
8-39: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winTrim the path used for the local package, not just the enable check.
enableTranscribeCppis derived from the trimmed env var, but.package(path: transcribeCppPackagePath)uses the raw, untrimmed value. A trailing newline/whitespace inMACPARAKEET_TRANSCRIBE_CPP_PACKAGE_PATH(common with CI heredocs/exports) would pass the enable check yet resolve to an invalid path, producing an obscure SwiftPM resolution failure — precisely in the release-build path called out in the comment on line 34-35.🔧 Proposed fix
if let transcribeCppPackagePath, enableTranscribeCpp { // Release builds must point this at the verified package assembled from the // owned MacParakeet fork and its pinned arm64 XCFramework. packageDependencies.append( - .package(name: "transcribe-cpp", path: transcribeCppPackagePath) + .package( + name: "transcribe-cpp", + path: transcribeCppPackagePath.trimmingCharacters(in: .whitespacesAndNewlines) + ) ) }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@Package.swift` around lines 8 - 39, Use the trimmed MACPARAKEET_TRANSCRIBE_CPP_PACKAGE_PATH value when appending the local transcribe-cpp dependency. Update the environment-value handling near enableTranscribeCpp so the .package(path:) call receives the same whitespace-trimmed path used for validation, while preserving the existing disabled behavior for empty values.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@benchmarks/asr/cohere_multilingual_speed.py`:
- Around line 213-225: Update the records serialization in the benchmark flow to
remove the absolute fixture path from each record. Replace the fixture field
with a stable fixture identifier and include the fixture digest, then redact or
migrate existing records so committed JSON contains no local paths.
- Around line 144-151: Update the transcript validation flow around the output
glob and count check to associate each fixture with its expected transcript and
content hash, then compare every generated transcript against the corresponding
shipped reference before publishing measurements. Reject mismatches as well as
missing or empty files, preserving fixture ordering and identifying which
fixture failed.
- Around line 161-176: Update the benchmark argument and provenance flow around
the runtime/model hash options and output generation to load immutable runtime
and model pins, release tag, immutability, and attestation metadata from the
checked-in release manifest instead of accepting caller-controlled values.
Verify the artifact digest and attestation against that manifest, reject any
mismatch before running or recording results, and emit the verified manifest
metadata in the evidence output.
In `@benchmarks/asr/run_macparakeet_fleurs.py`:
- Line 37: Update the benchmark logging near the Cohere engine handling so it
reports language=automatic instead of the unused hint value. Preserve hint
logging for engines that apply language hints, and use the existing Cohere
selection/configuration symbol to scope the change.
In `@Sources/CLI/Commands/ConfigCommand.swift`:
- Around line 119-124: Align the cohere-language CLI config spec and related
messaging to the same parsed language-code source used by parseCohereLanguage,
validation, override validation, and capability listing. Update
CLIConfigKeySpec’s valueSyntax and allowedValues, plus the corresponding
validation error and list/help output, so legacy-compatible values such as hi
and ru remain consistently accepted and advertised.
In `@spec/02-features.md`:
- Line 1896: Update the Cohere download size in the App size row to use the
consistent binary unit, changing the value to approximately 1.65 GiB while
leaving the other download-size estimates unchanged.
In `@spec/03-architecture.md`:
- Around line 519-524: Update the Markdown fences at spec/03-architecture.md
lines 519-524 and 768-775, and spec/06-stt-engine.md lines 101-105, to use the
text language identifier; preserve each fence’s existing content unchanged.
- Line 1056: Update the documented directory layout in spec/03-architecture.md
to include the models/stt/cohere/ leaf alongside stt/whisper/, and add the
revision-scoped-cache note for Cohere matching the documented file-location
table.
In `@spec/adr/001-parakeet-stt.md`:
- Line 15: Update the amendment in ADR-001 to state that the self-built owned
arm64 XCFramework prerequisite is satisfied, referencing the published
macparakeet-v0.1.3-arm64.1 release and checksum pin instead of saying release
remains blocked. Preserve the existing Cohere backend, scheduler, persistence,
and local classification descriptions.
---
Nitpick comments:
In `@Package.swift`:
- Around line 8-39: Use the trimmed MACPARAKEET_TRANSCRIBE_CPP_PACKAGE_PATH
value when appending the local transcribe-cpp dependency. Update the
environment-value handling near enableTranscribeCpp so the .package(path:) call
receives the same whitespace-trimmed path used for validation, while preserving
the existing disabled behavior for empty values.
In `@Tests/MacParakeetTests/STT/CohereTranscribeEngineTests.swift`:
- Around line 846-856: Update waitUntilLoadStarted and
waitUntilTranscriptionStarted to use deadline-bounded waiting that throws a
clear failure when their flags are not set in time, rather than yielding
indefinitely. Mark both methods as throwing and update their call sites around
the affected tests to use try await, preserving successful completion when the
corresponding state is reached.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 9f439883-c888-48ad-ade8-41ad84897030
⛔ Files ignored due to path filters (7)
scripts/dist/build_app_bundle.shis excluded by!**/dist/**scripts/dist/homebrew-tap-scaffold/HOWTO.mdis excluded by!**/dist/**scripts/dist/homebrew-tap-scaffold/README.mdis excluded by!**/dist/**scripts/dist/homebrew-tap-scaffold/macparakeet-cli.rbis excluded by!**/dist/**scripts/dist/sign_notarize.shis excluded by!**/dist/**scripts/dist/transcribe_cpp_release_pins.shis excluded by!**/dist/**scripts/dist/verify_transcribe_cpp_release.shis excluded by!**/dist/**
📒 Files selected for processing (69)
LICENSES/Apache-2.0.txtLICENSES/transcribe.cpp-MIT.txtLICENSES/transcribe.cpp-ggml-MIT.txtLICENSES/transcribe.cpp-miniz-MIT.txtPackage.swiftSources/CLI/CHANGELOG.mdSources/CLI/Commands/ConfigCommand.swiftSources/CLI/Commands/ModelsCommand.swiftSources/CLI/Commands/RetranscribeCommand.swiftSources/CLI/Commands/SpecCommand.swiftSources/CLI/Commands/TranscribeCommand.swiftSources/MacParakeet/App/DictationFlowCoordinator.swiftSources/MacParakeet/App/MenuBarCoordinator.swiftSources/MacParakeet/Views/Dictation/DictationOverlayController.swiftSources/MacParakeet/Views/Dictation/LoadingCaptionView.swiftSources/MacParakeet/Views/Settings/SettingsView.swiftSources/MacParakeetCore/AppFeatures.swiftSources/MacParakeetCore/STT/CohereTranscribeBackend.swiftSources/MacParakeetCore/STT/CohereTranscribeCppBackend.swiftSources/MacParakeetCore/STT/CohereTranscribeEngine.swiftSources/MacParakeetCore/STT/CohereTranscribeModel.swiftSources/MacParakeetCore/STT/README.mdSources/MacParakeetCore/STT/STTClient.swiftSources/MacParakeetCore/STT/STTClientProtocol.swiftSources/MacParakeetCore/STT/STTRuntime.swiftSources/MacParakeetCore/STT/STTScheduler.swiftSources/MacParakeetCore/STT/SpeechEngineCapabilities.swiftSources/MacParakeetCore/Services/AppPaths.swiftSources/MacParakeetCore/Services/LLM/InProcessModelDownloader.swiftSources/MacParakeetCore/Services/Telemetry/TelemetryEvent.swiftSources/MacParakeetCore/SpeechEnginePreference.swiftSources/MacParakeetViewModels/EngineSettingsViewModel.swiftSources/MacParakeetViewModels/TranscriptionViewModel.swiftTHIRD_PARTY_LICENSES.mdTests/CLITests/ModelLifecycleCommandTests.swiftTests/CLITests/SpecCommandTests.swiftTests/CLITests/TranscribeCommandTests.swiftTests/MacParakeetTests/STT/CohereTranscribeEngineTests.swiftTests/MacParakeetTests/STT/MockSTTClient.swiftTests/MacParakeetTests/STT/STTSchedulerTests.swiftTests/MacParakeetTests/STT/SpeechEngineCapabilitiesTests.swiftTests/MacParakeetTests/Services/LLM/InProcessModelDownloaderTests.swiftTests/MacParakeetTests/TelemetryServiceTests.swiftTests/MacParakeetTests/ViewModels/EngineSettingsViewModelTests.swiftTests/MacParakeetTests/ViewModels/TranscriptionViewModelTests.swiftbenchmarks/asr/README.mdbenchmarks/asr/cohere_multilingual_speed.pybenchmarks/asr/manifest.jsonbenchmarks/asr/results/cohere-transcribe-cpp-migration.mdbenchmarks/asr/results/cohere-transcribe-cpp-multilingual.jsonbenchmarks/asr/run_macparakeet.pybenchmarks/asr/run_macparakeet_fleurs.pybenchmarks/asr/speed_bench.pybenchmarks/asr/test_manifest.pydocs/cli-testing.mddocs/distribution.mdintegrations/README.mdintegrations/hermes/README.mdintegrations/openclaw/README.mdspec/00-vision.mdspec/02-features.mdspec/03-architecture.mdspec/04-ui-patterns.mdspec/06-stt-engine.mdspec/README.mdspec/adr/001-parakeet-stt.mdspec/adr/016-centralized-stt-runtime-scheduler.mdspec/adr/026-asr-engine-strategy.mdspec/adr/029-cohere-transcribe-cpp-backend.md
💤 Files with no reviewable changes (1)
- Sources/MacParakeet/App/MenuBarCoordinator.swift
📜 Review details
⏰ Context from checks skipped due to timeout. (1)
- GitHub Check: Greptile Review
🧰 Additional context used
📓 Path-based instructions (1)
**/*.swift
📄 CodeRabbit inference engine (AGENTS.md)
**/*.swift:MacParakeetCoreowns shared logic and must not own SwiftUI views; small AppKit-backed adapter services are allowed only when Foundation has no equivalent.
MacParakeetViewModelsshould contain@Observableview models that can be tested without the GUI.
New I/O should useasync/await; avoid introducing new completion-handler or Combine patterns.
When ordering or result sequencing matters, make the API async andawaitit instead of using fire-and-forgetTask.
Keep@MainActorwork short; move long-running I/O, model, process, and audio work off the actor, then hop back for UI state.
Database access must use GRDB repositories, roughly one repository per table.
UI buttons should use.parakeetAction(...); do not tint whole hosting roots coral.
Files:
Sources/CLI/Commands/RetranscribeCommand.swiftSources/CLI/Commands/ModelsCommand.swiftSources/MacParakeetCore/Services/AppPaths.swiftSources/MacParakeetCore/STT/STTClientProtocol.swiftSources/MacParakeet/App/DictationFlowCoordinator.swiftTests/CLITests/ModelLifecycleCommandTests.swiftSources/MacParakeet/Views/Dictation/DictationOverlayController.swiftSources/MacParakeetCore/AppFeatures.swiftSources/MacParakeetCore/STT/SpeechEngineCapabilities.swiftTests/CLITests/SpecCommandTests.swiftSources/MacParakeet/Views/Dictation/LoadingCaptionView.swiftSources/MacParakeetCore/STT/CohereTranscribeModel.swiftTests/MacParakeetTests/ViewModels/TranscriptionViewModelTests.swiftSources/MacParakeetCore/Services/LLM/InProcessModelDownloader.swiftSources/CLI/Commands/TranscribeCommand.swiftTests/MacParakeetTests/Services/LLM/InProcessModelDownloaderTests.swiftSources/CLI/Commands/SpecCommand.swiftSources/MacParakeetCore/Services/Telemetry/TelemetryEvent.swiftTests/MacParakeetTests/STT/SpeechEngineCapabilitiesTests.swiftSources/MacParakeetViewModels/TranscriptionViewModel.swiftTests/CLITests/TranscribeCommandTests.swiftTests/MacParakeetTests/TelemetryServiceTests.swiftSources/CLI/Commands/ConfigCommand.swiftSources/MacParakeetCore/STT/CohereTranscribeBackend.swiftSources/MacParakeetCore/STT/STTClient.swiftSources/MacParakeetCore/STT/STTScheduler.swiftTests/MacParakeetTests/ViewModels/EngineSettingsViewModelTests.swiftSources/MacParakeetCore/SpeechEnginePreference.swiftPackage.swiftSources/MacParakeetCore/STT/CohereTranscribeCppBackend.swiftTests/MacParakeetTests/STT/MockSTTClient.swiftTests/MacParakeetTests/STT/STTSchedulerTests.swiftSources/MacParakeetViewModels/EngineSettingsViewModel.swiftSources/MacParakeetCore/STT/STTRuntime.swiftSources/MacParakeet/Views/Settings/SettingsView.swiftTests/MacParakeetTests/STT/CohereTranscribeEngineTests.swiftSources/MacParakeetCore/STT/CohereTranscribeEngine.swift
🧠 Learnings (6)
📚 Learning: 2026-04-16T03:48:03.903Z
Learnt from: moona3k
Repo: moona3k/macparakeet PR: 111
File: Sources/MacParakeet/Views/Transcription/PortalDropZone.swift:40-47
Timestamp: 2026-04-16T03:48:03.903Z
Learning: In SwiftUI, don’t flag `accessibilityReduceMotion` violations for *user-initiated, direct-response* feedback animations. If an animation is tied to a real-time user interaction (e.g., drag state changes like `isDragging`) and provides immediate state feedback (such as an opacity transition from ~0.7→0.9 while dragging), treat it as action feedback rather than automatic/decorative motion. Only expect `accessibilityReduceMotion` gating for automatic or non-essential animations; when the motion is driven by explicit user input, it’s acceptable to leave it ungated.
Applied to files:
Sources/CLI/Commands/RetranscribeCommand.swiftSources/CLI/Commands/ModelsCommand.swiftSources/MacParakeetCore/Services/AppPaths.swiftSources/MacParakeetCore/STT/STTClientProtocol.swiftSources/MacParakeet/App/DictationFlowCoordinator.swiftSources/MacParakeet/Views/Dictation/DictationOverlayController.swiftSources/MacParakeetCore/AppFeatures.swiftSources/MacParakeetCore/STT/SpeechEngineCapabilities.swiftSources/MacParakeet/Views/Dictation/LoadingCaptionView.swiftSources/MacParakeetCore/STT/CohereTranscribeModel.swiftSources/MacParakeetCore/Services/LLM/InProcessModelDownloader.swiftSources/CLI/Commands/TranscribeCommand.swiftSources/CLI/Commands/SpecCommand.swiftSources/MacParakeetCore/Services/Telemetry/TelemetryEvent.swiftSources/MacParakeetViewModels/TranscriptionViewModel.swiftSources/CLI/Commands/ConfigCommand.swiftSources/MacParakeetCore/STT/CohereTranscribeBackend.swiftSources/MacParakeetCore/STT/STTClient.swiftSources/MacParakeetCore/STT/STTScheduler.swiftSources/MacParakeetCore/SpeechEnginePreference.swiftSources/MacParakeetCore/STT/CohereTranscribeCppBackend.swiftSources/MacParakeetViewModels/EngineSettingsViewModel.swiftSources/MacParakeetCore/STT/STTRuntime.swiftSources/MacParakeet/Views/Settings/SettingsView.swiftSources/MacParakeetCore/STT/CohereTranscribeEngine.swift
📚 Learning: 2026-04-07T04:06:36.832Z
Learnt from: moona3k
Repo: moona3k/macparakeet PR: 76
File: Sources/MacParakeet/Views/MeetingRecording/MeetingRecordingPanelView.swift:134-142
Timestamp: 2026-04-07T04:06:36.832Z
Learning: In the moona3k/macparakeet codebase, treat an NSPasteboard usage sequence of `NSPasteboard.general.clearContents()` immediately followed by `NSPasteboard.general.setString(_, forType: .string)` as an intentional pattern. Do not flag the unchecked/ignored return value of `setString` in isolation when this `clearContents()`→`setString` sequence is used (as seen in ClipboardService and related views). If you believe this behavior is incorrect, changes should be validated and applied via a codebase-wide sweep rather than a single-file fix.
Applied to files:
Sources/MacParakeet/App/DictationFlowCoordinator.swiftSources/MacParakeet/Views/Dictation/DictationOverlayController.swiftSources/MacParakeet/Views/Dictation/LoadingCaptionView.swiftSources/MacParakeet/Views/Settings/SettingsView.swift
📚 Learning: 2026-04-25T21:55:25.954Z
Learnt from: moona3k
Repo: moona3k/macparakeet PR: 138
File: Tests/CLITests/PromptsCommandTests.swift:158-172
Timestamp: 2026-04-25T21:55:25.954Z
Learning: When reviewing Swift tests in this repo, remember that `DatabaseManager()` (the default test database initializer) seeds 6 built-in prompts during migration. As a result, code paths like `PromptRepository.fetchAll()` will not return an empty array, and positional assumptions/ordering-based assertions (e.g., checking `parsed?.first?[
Applied to files:
Tests/CLITests/ModelLifecycleCommandTests.swiftTests/CLITests/SpecCommandTests.swiftTests/MacParakeetTests/ViewModels/TranscriptionViewModelTests.swiftTests/MacParakeetTests/Services/LLM/InProcessModelDownloaderTests.swiftTests/MacParakeetTests/STT/SpeechEngineCapabilitiesTests.swiftTests/CLITests/TranscribeCommandTests.swiftTests/MacParakeetTests/TelemetryServiceTests.swiftTests/MacParakeetTests/ViewModels/EngineSettingsViewModelTests.swiftTests/MacParakeetTests/STT/MockSTTClient.swiftTests/MacParakeetTests/STT/STTSchedulerTests.swiftTests/MacParakeetTests/STT/CohereTranscribeEngineTests.swift
📚 Learning: 2026-05-13T02:39:59.049Z
Learnt from: moona3k
Repo: moona3k/macparakeet PR: 283
File: Tests/CLITests/TransformsCommandTests.swift:225-268
Timestamp: 2026-05-13T02:39:59.049Z
Learning: In CLI contract tests under Tests/CLITests (Swift), round-trip tests that exercise the `--database <path>` argument should use a file-backed `DatabaseManager(path:)` (on-disk SQLite) rather than an in-memory queue. Each CLI subcommand invocation independently reopens `DatabaseManager(path:)` from the provided path, so an in-memory `DatabaseQueue` cannot be shared across subcommand runs. Only repository-level history tests (outside the CLI `--database` contract tests) may use in-memory SQLite.
Applied to files:
Tests/CLITests/ModelLifecycleCommandTests.swiftTests/CLITests/SpecCommandTests.swiftTests/CLITests/TranscribeCommandTests.swift
📚 Learning: 2026-05-12T20:04:36.900Z
Learnt from: moona3k
Repo: moona3k/macparakeet PR: 278
File: Sources/MacParakeet/Views/Transforms/TransformSpikeProgressPanelController.swift:15-18
Timestamp: 2026-05-12T20:04:36.900Z
Learning: In this codebase, non-activating overlay panels are implemented as private, per-controller NSPanel subclasses defined locally within each controller file. The subclass should override `canBecomeKey` and `canBecomeMain` to return `false`. During review, follow this existing pattern and avoid suggesting or introducing a shared/centralized `KeylessPanel` abstraction (e.g., don’t refactor these overlays to a common base type).
Applied to files:
Sources/MacParakeet/Views/Dictation/DictationOverlayController.swift
📚 Learning: 2026-04-09T02:00:51.656Z
Learnt from: moona3k
Repo: moona3k/macparakeet PR: 93
File: Tests/MacParakeetTests/Audio/ObjCExceptionBridgeTests.swift:6-98
Timestamp: 2026-04-09T02:00:51.656Z
Learning: In this repo, unit tests that only exercise internal infrastructure/plumbing (e.g., exception trampolines, bridges, shims) should not require separate requirement IDs in `spec/kernel/traceability.md`. If a plumbing test exists only to make an existing production code path crash-safe or correct, treat it as covered by the existing product requirement that governs that code path (for example, dictation tests covered by `REQ-DICT-001`). Do not add new `REQ-CRASH-*` (or similar) traceability entries for pure infrastructure tests, as this is considered spec bloat per `spec/10-ai-coding-method.md`.
Applied to files:
Tests/MacParakeetTests/ViewModels/TranscriptionViewModelTests.swiftTests/MacParakeetTests/Services/LLM/InProcessModelDownloaderTests.swiftTests/MacParakeetTests/STT/SpeechEngineCapabilitiesTests.swiftTests/MacParakeetTests/TelemetryServiceTests.swiftTests/MacParakeetTests/ViewModels/EngineSettingsViewModelTests.swiftTests/MacParakeetTests/STT/MockSTTClient.swiftTests/MacParakeetTests/STT/STTSchedulerTests.swiftTests/MacParakeetTests/STT/CohereTranscribeEngineTests.swift
🪛 ast-grep (0.44.1)
benchmarks/asr/cohere_multilingual_speed.py
[info] 246-246: use jsonify instead of json.dumps for JSON output
Context: json.dumps(payload, ensure_ascii=False, indent=2)
Note: [CWE-116] Improper Encoding or Escaping of Output.
(use-jsonify)
[error] 42-47: Command coming from incoming request
Context: subprocess.run(
command,
text=True,
capture_output=True,
check=False,
)
Note: [CWE-78] Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection').
(subprocess-from-request)
[error] 72-77: Command coming from incoming request
Context: subprocess.run(
["/usr/bin/afinfo", "-b", str(path)],
text=True,
capture_output=True,
check=False,
)
Note: [CWE-78] Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection').
(subprocess-from-request)
[error] 124-130: Command coming from incoming request
Context: subprocess.run(
command,
text=True,
capture_output=True,
env=environment,
check=False,
)
Note: [CWE-78] Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection').
(subprocess-from-request)
[error] 42-47: Use of unsanitized data to create processes
Context: subprocess.run(
command,
text=True,
capture_output=True,
check=False,
)
Note: [CWE-78] Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection').
(os-system-unsanitized-data)
[error] 124-130: Use of unsanitized data to create processes
Context: subprocess.run(
command,
text=True,
capture_output=True,
env=environment,
check=False,
)
Note: [CWE-78] Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection').
(os-system-unsanitized-data)
🪛 LanguageTool
LICENSES/Apache-2.0.txt
[style] ~162-~162: ‘any and all’ might be wordy. Consider a shorter alternative.
Context: ...ge, computer failure or malfunction, or any and all other commercial damages or losse...
(EN_WORDINESS_PREMIUM_ANY_AND_ALL)
spec/adr/029-cohere-transcribe-cpp-backend.md
[grammar] ~102-~102: Use a hyphen to join words.
Context: ...timings, boundary stitching remains text based and may retain or remove a short r...
(QB_NEW_EN_HYPHEN)
docs/distribution.md
[style] ~26-~26: The double modal “required owned” is nonstandard (only accepted in certain dialects). Consider “to be owned”.
Context: ...package in source builds and a required owned artifact in production builds. A releas...
(NEEDS_FIXED)
🪛 markdownlint-cli2 (0.23.0)
spec/06-stt-engine.md
[warning] 101-101: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
spec/03-architecture.md
[warning] 519-519: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
[warning] 768-768: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
🪛 OpenGrep (1.25.0)
benchmarks/asr/results/cohere-transcribe-cpp-multilingual.json
[ERROR] 107-107: Possible credit card number (PAN) detected in source code. Credit card numbers should never be hardcoded or stored in source files. Use a secrets manager or tokenization service instead.
(coderabbit.pii.credit-card-number)
🪛 Ruff (0.15.21)
benchmarks/asr/cohere_multilingual_speed.py
[error] 43-43: subprocess call: check for execution of untrusted input
(S603)
[error] 73-73: subprocess call: check for execution of untrusted input
(S603)
[error] 125-125: subprocess call: check for execution of untrusted input
(S603)
🔇 Additional comments (76)
Sources/MacParakeetCore/STT/README.md (1)
69-89: LGTM!Also applies to: 123-124
benchmarks/asr/manifest.json (1)
147-161: LGTM!Also applies to: 450-451
benchmarks/asr/run_macparakeet.py (1)
17-17: LGTM!Also applies to: 42-42
benchmarks/asr/speed_bench.py (1)
51-51: LGTM!benchmarks/asr/test_manifest.py (1)
52-56: LGTM!THIRD_PARTY_LICENSES.md (1)
49-84: LGTM!Also applies to: 168-180
docs/cli-testing.md (1)
240-256: LGTM!docs/distribution.md (1)
19-86: LGTM!integrations/README.md (1)
19-20: LGTM!Also applies to: 96-99, 323-325
integrations/hermes/README.md (1)
32-35: LGTM!integrations/openclaw/README.md (1)
26-28: LGTM!Also applies to: 39-41, 87-95
spec/adr/026-asr-engine-strategy.md (1)
7-9: LGTM!Also applies to: 18-20, 63-69
spec/adr/029-cohere-transcribe-cpp-backend.md (1)
1-193: LGTM!spec/00-vision.md (1)
477-477: LGTM!spec/02-features.md (1)
727-727: LGTM!Also applies to: 758-758, 771-771, 1916-1916
spec/03-architecture.md (1)
85-85: LGTM!Also applies to: 104-104, 415-415, 483-483, 516-516, 755-766, 1090-1091, 1241-1241
spec/04-ui-patterns.md (1)
986-989: LGTM!spec/06-stt-engine.md (1)
75-96: LGTM!Also applies to: 97-100, 106-108
spec/README.md (1)
4-4: LGTM!Also applies to: 53-53, 116-119, 284-286
spec/adr/001-parakeet-stt.md (1)
224-236: LGTM!Also applies to: 276-277
spec/adr/016-centralized-stt-runtime-scheduler.md (1)
13-13: LGTM!Also applies to: 55-55
LICENSES/Apache-2.0.txt (1)
1-203: LGTM!LICENSES/transcribe.cpp-MIT.txt (1)
1-22: LGTM!Sources/MacParakeetCore/STT/STTClient.swift (1)
10-10: LGTM!Also applies to: 111-114
Sources/MacParakeetCore/STT/STTClientProtocol.swift (1)
152-157: LGTM!Sources/MacParakeetCore/STT/STTScheduler.swift (2)
26-27: LGTM!
372-398: 🩺 Stability & AvailabilityNo change needed.
models delete cohere-transcribealready protects the currently selected Cohere engine, so this path does not bypass the delete guard unless--forceis used.Sources/MacParakeetViewModels/EngineSettingsViewModel.swift (1)
53-56: LGTM!Also applies to: 113-116, 196-196, 281-283, 1410-1441, 1493-1493
Sources/CLI/CHANGELOG.md (1)
104-111: LGTM!Tests/MacParakeetTests/STT/MockSTTClient.swift (1)
10-10: LGTM!Also applies to: 32-32, 569-572
Tests/MacParakeetTests/STT/STTSchedulerTests.swift (1)
496-546: LGTM!Also applies to: 1280-1294, 1494-1515, 1756-1766, 1932-1940
Tests/MacParakeetTests/ViewModels/EngineSettingsViewModelTests.swift (1)
95-95: LGTM!Also applies to: 364-386, 793-815
Tests/MacParakeetTests/ViewModels/TranscriptionViewModelTests.swift (1)
3139-3142: LGTM!LICENSES/transcribe.cpp-ggml-MIT.txt (1)
1-21: LGTM!LICENSES/transcribe.cpp-miniz-MIT.txt (1)
1-22: LGTM!Sources/MacParakeetCore/STT/CohereTranscribeModel.swift (3)
3-37: LGTM!
39-94: LGTM!
96-117: LGTM!Sources/MacParakeetCore/STT/CohereTranscribeEngine.swift (6)
48-152: LGTM!
171-251: LGTM!
255-289: LGTM!
291-381: LGTM!
666-666: LGTM!Also applies to: 711-774
785-811: LGTM!Also applies to: 844-929
Sources/MacParakeetCore/STT/STTRuntime.swift (2)
41-41: LGTM!Also applies to: 64-67
1563-1577: 🩺 Stability & AvailabilityNo change needed.
STTScheduler.deleteCohereModel()holdsspeechEngineSwitchTaskand disables job admission for the full operation, so new Cohere transcription jobs cannot be admitted whileSTTRuntime.deleteCohereModel()is suspended duringunloadCohere().Sources/MacParakeet/Views/Dictation/DictationOverlayController.swift (1)
210-212: LGTM!Sources/MacParakeetCore/Services/LLM/InProcessModelDownloader.swift (1)
457-462: LGTM!Sources/MacParakeetCore/SpeechEnginePreference.swift (1)
7-9: LGTM!Also applies to: 27-29, 170-172, 186-203
Tests/MacParakeetTests/STT/CohereTranscribeEngineTests.swift (4)
5-12: LGTM!Also applies to: 258-334
343-438: LGTM!
463-646: LGTM!
664-845: LGTM!Also applies to: 857-877
Tests/MacParakeetTests/Services/LLM/InProcessModelDownloaderTests.swift (1)
6-18: LGTM!Tests/MacParakeetTests/TelemetryServiceTests.swift (1)
725-726: LGTM!Package.swift (1)
54-82: LGTM!Also applies to: 173-173, 186-186
Sources/MacParakeetCore/STT/CohereTranscribeBackend.swift (1)
1-156: LGTM!Sources/MacParakeetCore/STT/CohereTranscribeCppBackend.swift (2)
28-35: 🩺 Stability & AvailabilityConfirm
Transcribe.initBackends()is safe to call on every reload.
ensureCompatible()/initBackends()run again on everyload(), including any reload after a priorunload()(e.g. re-selecting Cohere after switching engines away and back). Public transcribe.cpp docs describe per-Modelrun serialization but don't document whether repeatedinitBackends()calls across a process lifetime are idempotent/cheap or could reinitialize global GPU/backend state. Given the load path is exercised through the scheduler's lifecycle-safe unload/delete flow, a non-idempotent repeated init could surface only on the "unload → later reselect Cohere → load again" path, which may be under-covered by the current test surface.Worth confirming directly against the pinned
transcribe.cppv0.1.3 Swift bindings/header docs, or adding a regression test that loads, unloads, and reloadsTranscribeCppCohereBackendtwice in the same process.
[medium]
41-69: LGTM!Also applies to: 71-131, 133-167
Sources/CLI/Commands/ConfigCommand.swift (1)
42-42: LGTM!Also applies to: 307-312, 603-610
Sources/CLI/Commands/ModelsCommand.swift (1)
562-562: LGTM!Sources/CLI/Commands/SpecCommand.swift (1)
219-221: LGTM!Also applies to: 275-277
Sources/CLI/Commands/TranscribeCommand.swift (1)
110-111: LGTM!Also applies to: 297-312, 625-634
Sources/MacParakeet/App/DictationFlowCoordinator.swift (1)
838-846: LGTM!Sources/MacParakeetCore/AppFeatures.swift (1)
72-79: LGTM!Sources/MacParakeetCore/Services/AppPaths.swift (1)
123-126: LGTM!Sources/CLI/Commands/RetranscribeCommand.swift (1)
147-147: LGTM!Sources/MacParakeet/Views/Dictation/LoadingCaptionView.swift (1)
41-41: LGTM!Also applies to: 52-52
Sources/MacParakeet/Views/Settings/SettingsView.swift (1)
567-567: LGTM!Also applies to: 613-614, 2203-2206, 2572-2580, 2592-2593, 2873-2873, 2996-2996
Sources/MacParakeetCore/STT/SpeechEngineCapabilities.swift (1)
359-367: LGTM!Sources/MacParakeetCore/Services/Telemetry/TelemetryEvent.swift (1)
1816-1820: LGTM!Sources/MacParakeetViewModels/TranscriptionViewModel.swift (1)
809-810: LGTM!Also applies to: 1451-1451
Tests/CLITests/ModelLifecycleCommandTests.swift (1)
152-152: LGTM!Tests/CLITests/SpecCommandTests.swift (1)
357-357: LGTM!Tests/CLITests/TranscribeCommandTests.swift (1)
279-280: LGTM!Also applies to: 382-383
Tests/MacParakeetTests/STT/SpeechEngineCapabilitiesTests.swift (1)
111-116: LGTM!
Fail fast when the arm64-only transcribe.cpp package is combined with a universal build, preserve legacy Cohere CLI language values, and bound native lifecycle test waits. Harden the multilingual benchmark with checked-in runtime, model, fixture, transcript, release, and attestation provenance, and correct the migration documentation.
There was a problem hiding this comment.
🧹 Nitpick comments (1)
benchmarks/asr/test_cohere_multilingual_speed.py (1)
62-120: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winConsider covering more
validate_release_metadatafailure branches.Only the immutability-failure branch is exercised here. Given this function is the security-critical provenance gate, adding a couple more
assertRaisesRegexcases (e.g., mismatchedpredicate.tag, mismatched assetdigest, or missing commit-subject PURL) would catch regressions in the other checks at low cost.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@benchmarks/asr/test_cohere_multilingual_speed.py` around lines 62 - 120, Extend test_release_metadata_requires_matching_immutable_attestation to cover additional validate_release_metadata rejection branches, such as a mismatched attestation predicate tag, mismatched asset digest, and missing commit-subject PURL. For each mutation, use assertRaisesRegex with the expected validation message, while preserving the existing valid case and immutability failure check.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@benchmarks/asr/test_cohere_multilingual_speed.py`:
- Around line 62-120: Extend
test_release_metadata_requires_matching_immutable_attestation to cover
additional validate_release_metadata rejection branches, such as a mismatched
attestation predicate tag, mismatched asset digest, and missing commit-subject
PURL. For each mutation, use assertRaisesRegex with the expected validation
message, while preserving the existing valid case and immutability failure
check.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 5454354f-108e-482c-8611-125b2137f0c0
⛔ Files ignored due to path filters (2)
scripts/dist/build_app_bundle.shis excluded by!**/dist/**scripts/dist/verify_transcribe_cpp_release.shis excluded by!**/dist/**
📒 Files selected for processing (20)
Package.swiftSources/CLI/Commands/ConfigCommand.swiftSources/CLI/Commands/TranscribeCommand.swiftTests/CLITests/ConfigCommandTests.swiftTests/CLITests/SpecCommandTests.swiftTests/CLITests/TranscribeCommandTests.swiftTests/MacParakeetTests/STT/CohereTranscribeEngineTests.swiftbenchmarks/asr/README.mdbenchmarks/asr/cohere_multilingual_speed.pybenchmarks/asr/cohere_transcribe_cpp_release.jsonbenchmarks/asr/results/cohere-transcribe-cpp-migration.mdbenchmarks/asr/results/cohere-transcribe-cpp-multilingual.jsonbenchmarks/asr/run_all.shbenchmarks/asr/run_macparakeet_fleurs.pybenchmarks/asr/test_cohere_multilingual_speed.pydocs/distribution.mdspec/02-features.mdspec/03-architecture.mdspec/06-stt-engine.mdspec/adr/001-parakeet-stt.md
🚧 Files skipped from review as they are similar to previous changes (12)
- Tests/CLITests/SpecCommandTests.swift
- benchmarks/asr/run_macparakeet_fleurs.py
- Sources/CLI/Commands/ConfigCommand.swift
- benchmarks/asr/results/cohere-transcribe-cpp-migration.md
- Tests/CLITests/TranscribeCommandTests.swift
- docs/distribution.md
- benchmarks/asr/results/cohere-transcribe-cpp-multilingual.json
- Package.swift
- spec/06-stt-engine.md
- spec/03-architecture.md
- Tests/MacParakeetTests/STT/CohereTranscribeEngineTests.swift
- benchmarks/asr/README.md
📜 Review details
⏰ Context from checks skipped due to timeout. (2)
- GitHub Check: Greptile Review
- GitHub Check: swift-test
🧰 Additional context used
📓 Path-based instructions (1)
**/*.swift
📄 CodeRabbit inference engine (AGENTS.md)
**/*.swift:MacParakeetCoreowns shared logic and must not own SwiftUI views; small AppKit-backed adapter services are allowed only when Foundation has no equivalent.
MacParakeetViewModelsshould contain@Observableview models that can be tested without the GUI.
New I/O should useasync/await; avoid introducing new completion-handler or Combine patterns.
When ordering or result sequencing matters, make the API async andawaitit instead of using fire-and-forgetTask.
Keep@MainActorwork short; move long-running I/O, model, process, and audio work off the actor, then hop back for UI state.
Database access must use GRDB repositories, roughly one repository per table.
UI buttons should use.parakeetAction(...); do not tint whole hosting roots coral.
Files:
Tests/CLITests/ConfigCommandTests.swiftSources/CLI/Commands/TranscribeCommand.swift
🧠 Learnings (3)
📚 Learning: 2026-04-25T21:55:25.954Z
Learnt from: moona3k
Repo: moona3k/macparakeet PR: 138
File: Tests/CLITests/PromptsCommandTests.swift:158-172
Timestamp: 2026-04-25T21:55:25.954Z
Learning: When reviewing Swift tests in this repo, remember that `DatabaseManager()` (the default test database initializer) seeds 6 built-in prompts during migration. As a result, code paths like `PromptRepository.fetchAll()` will not return an empty array, and positional assumptions/ordering-based assertions (e.g., checking `parsed?.first?[
Applied to files:
Tests/CLITests/ConfigCommandTests.swift
📚 Learning: 2026-05-13T02:39:59.049Z
Learnt from: moona3k
Repo: moona3k/macparakeet PR: 283
File: Tests/CLITests/TransformsCommandTests.swift:225-268
Timestamp: 2026-05-13T02:39:59.049Z
Learning: In CLI contract tests under Tests/CLITests (Swift), round-trip tests that exercise the `--database <path>` argument should use a file-backed `DatabaseManager(path:)` (on-disk SQLite) rather than an in-memory queue. Each CLI subcommand invocation independently reopens `DatabaseManager(path:)` from the provided path, so an in-memory `DatabaseQueue` cannot be shared across subcommand runs. Only repository-level history tests (outside the CLI `--database` contract tests) may use in-memory SQLite.
Applied to files:
Tests/CLITests/ConfigCommandTests.swift
📚 Learning: 2026-04-16T03:48:03.903Z
Learnt from: moona3k
Repo: moona3k/macparakeet PR: 111
File: Sources/MacParakeet/Views/Transcription/PortalDropZone.swift:40-47
Timestamp: 2026-04-16T03:48:03.903Z
Learning: In SwiftUI, don’t flag `accessibilityReduceMotion` violations for *user-initiated, direct-response* feedback animations. If an animation is tied to a real-time user interaction (e.g., drag state changes like `isDragging`) and provides immediate state feedback (such as an opacity transition from ~0.7→0.9 while dragging), treat it as action feedback rather than automatic/decorative motion. Only expect `accessibilityReduceMotion` gating for automatic or non-essential animations; when the motion is driven by explicit user input, it’s acceptable to leave it ungated.
Applied to files:
Sources/CLI/Commands/TranscribeCommand.swift
🪛 ast-grep (0.44.1)
benchmarks/asr/test_cohere_multilingual_speed.py
[warning] 26-26: Regex pattern passed to re is built from a non-literal (variable, call, concatenation, or f-string) value. If that value is attacker-controlled it can introduce a malicious pattern with catastrophic backtracking (ReDoS). Use a hardcoded literal pattern, or validate/escape untrusted input with re.escape() and bound the regex complexity before compiling.
Context: re.search(rf'^{name}="([^"]+)"$', pins, re.MULTILINE)
Note: [CWE-1333] Inefficient Regular Expression Complexity.
(redos-non-literal-regex-python)
benchmarks/asr/cohere_multilingual_speed.py
[error] 97-102: Use of unsanitized data to create processes
Context: subprocess.run(
command,
text=True,
capture_output=True,
check=False,
)
Note: [CWE-78] Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection').
(os-system-unsanitized-data)
[error] 97-102: Command coming from incoming request
Context: subprocess.run(
command,
text=True,
capture_output=True,
check=False,
)
Note: [CWE-78] Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection').
(subprocess-from-request)
🪛 Ruff (0.15.21)
benchmarks/asr/cohere_multilingual_speed.py
[error] 98-98: subprocess call: check for execution of untrusted input
(S603)
🔇 Additional comments (11)
Sources/CLI/Commands/TranscribeCommand.swift (1)
110-110: LGTM!Also applies to: 302-308, 624-626
Tests/CLITests/ConfigCommandTests.swift (1)
551-560: LGTM!benchmarks/asr/cohere_transcribe_cpp_release.json (2)
3-12: 🎯 Functional CorrectnessVerify the custom attestation predicate type/schema against the fork's actual release workflow output.
attestation_predicate_typeis pinned to"https://in-toto.io/attestation/release/v0.2", andvalidate_release_metadatainbenchmarks/asr/cohere_multilingual_speed.py(lines 154-162) checks top-levelpredicate.repository/predicate.tagfields directly against this type. This doesn't match GitHub's standard build-provenance attestation format, whose default/well-known predicate type ishttps://slsa.dev/provenance/v1with fields nested underpredicate.buildDefinition.externalParameters.workflow.*, nor any predicate type in in-toto's official catalog (link, test-result, human-review, runtime-trace, SCAI, VSA). Custom predicate URIs are permitted by the in-toto spec, so this is plausible if the owned fork's release CI emits a bespoke attestation with exactly this shape — but if the fork's workflow instead uses the standardgh/SLSA provenance format,validate_release_metadatawill always fail closed (safe, but blocks every benchmark/release-verification run).Please confirm the owned fork's release workflow (
DudeMeister23/transcribe.cppat the pinned tag) actually emits an attestation withpredicateType: "https://in-toto.io/attestation/release/v0.2"and this exactpredicate.repository/predicate.tag/subjectshape.
13-42: LGTM!benchmarks/asr/cohere_multilingual_speed.py (3)
97-115: 🩺 Stability & Availability | ⚡ Quick winAdd a timeout to
ghsubprocess calls.
command_json()runssubprocess.runwith notimeout, and it backs bothgh release viewandgh release verifyinverify_release_provenance. Ifghhangs (auth prompt, network stall), the benchmark run blocks indefinitely instead of failing fast.The static-analysis "OS command injection"/"subprocess from request" hints on this block are false positives: `subprocess.run` is called with a list (no `shell=True`), and the command arguments (`runtime["release_tag"]`, `runtime["repository"]`) come from the checked-in, schema-validated release manifest, not from attacker-controlled/request input.🛡️ Proposed fix
def command_json(command: list[str], description: str) -> dict: process = subprocess.run( command, text=True, capture_output=True, check=False, + timeout=60, )Source: Linters/SAST tools
36-95: LGTM! The fail-closed provenance verification, exact-match transcript validation, and stable fixture-ID/digest publishing (replacing absolute paths) all address the prior review feedback correctly.Also applies to: 118-263
392-499: LGTM! Provenance verification happens before any fixture/model use, and the payload now records verified runtime/model provenance fields plus stable fixture identifiers instead of local paths.benchmarks/asr/run_all.sh (1)
27-27: LGTM!benchmarks/asr/test_cohere_multilingual_speed.py (1)
1-170: LGTM otherwise — good coverage of manifest/pin parity, fixture checksum mismatch, and transcript-mismatch fail-closed behavior, and the committed-result assertions correctly guard against reintroducing absolute paths.spec/02-features.md (1)
727-727: LGTM! The unit for the Cohere download size was corrected to~1.65 GiB(matches the pinned 1,770,270,208-byte model size incohere_transcribe_cpp_release.json), addressing the prior review comment, and the language/local-execution wording is consistent with the new automatic-detection, transcribe.cpp-backed behavior.Also applies to: 758-758, 771-771, 1896-1896, 1916-1916
spec/adr/001-parakeet-stt.md (1)
15-15: LGTM! The amendment now states the arm64 XCFramework prerequisite is satisfied via the pinned immutable release and SHA-256, resolving the prior contradiction with ADR-029's evidence.
Summary
This replaces only Cohere Transcribe's FluidAudio/CoreML execution backend with a narrow transcribe.cpp adapter. Cohere remains the same opt-in local product engine, with the same persisted engine id, settings compatibility, CLI routes, scheduler admission, meeting leases, transcript persistence, telemetry identity, and STTResult contract.
Why this change is worthwhile
This is not runtime churn for its own sake. It turns Cohere from an accurate but operationally expensive option into a more practical local engine while reducing supply-chain and lifecycle risk:
Architecture:
Parakeet, WhisperKit, Nemotron, meeting capture, transforms, and unrelated STT behavior remain unchanged.
Exact pins
GitHub reports the release as immutable. gh release verify validated the GitHub Sigstore release attestation binding the exact fork commit and artifact digest. A fresh release download matched the measured and pinned archive byte for byte.
Distribution and licenses
transcribe.cpp, its Swift wrapper, ggml, and miniz are MIT licensed. The Cohere GGUF model is Apache-2.0. The source notices and full Apache-2.0 text are retained under LICENSES. Production packaging copies the notices and THIRD_PARTY_LICENSES.md into the app Legal resources before signing.
The production verifier fails closed unless the package checkout, repository, commit, wrapper version, release metadata, artifact filename and SHA-256, materialized XCFramework contents, arm64-only binary, vendored ggml/miniz provenance, and retained notices all match the committed pins.
The owned fork and immutable XCFramework release prerequisite is complete. No GitHub fork or artifact publication remains outstanding for this PR.
Validation
Linked Cohere focused suite: 50 tests, 1 expected unavailable-runtime skip, 0 failures.
Unlinked Cohere focused suite: 49 tests, 0 failures.
Full Swift final gate, run once: 5,087 XCTest tests, 19 skipped, 0 failures; 17 Swift Testing tests passed.
Owned native real-model CTest: 2 of 2 passed.
Owned Swift wrapper suite: 56 tests executed, 41 unrelated-model skips, 0 failures.
Production release verifier passed against a fresh download of the immutable release.
Benchmark manifest validation and Python compilation passed.
Swift format lint passed for the Cohere adapter, engine, model pins, and focused tests.
git diff --check and the repository Unicode policy scan passed.
Review-fix focused suite: 214 tests, 1 expected unavailable-runtime skip, 0 failures.
Exact Swift 6 language-mode build passed.
Repository-only ASR benchmark verification passed, including scorer tests and committed multilingual/full-English rescoring.
GitHub CI run 30166261704 passed the release build, CLI smoke, release-bundle smoke, concurrency gate, Swift 6 build, and complete Swift suite on final head 1a38c0a.
Greptile and CodeRabbit passed on the final head; all review threads are resolved.
no-mistakes is not installed in this checkout. The hosted CI and repository review gates are complete.
Multilingual runtime evidence
Measured through the real macparakeet-cli without language hints on an Apple M1 Max with 64 GB, Metal compute. All cold and twelve repeated warm transcripts matched their fixture references.
The historical FluidAudio/CoreML reference was about 73 seconds cold, about 11x warm, and about 11.6 GB peak RSS on an Apple M4 Pro with 48 GB. That is a directional backend comparison only because the hardware and aggregate fixture methodology differ.
Known limitations
Summary by cubic
Replaces Cohere’s CoreML backend with a pinned
transcribe.cppadapter while keeping thecohereengine id and product behavior. Adds automatic language detection, a smaller Q5_K_M model (~1.65 GB), andmetal/cpucompute policies with reproducible, checksummed distribution.Refactors
TranscribeCppCohereBackendactor with serialized model/session access, cancellation forwarding, and deterministic teardown.~/Library/Application Support/MacParakeet/models/stt/cohere/with resumable downloads and exact size/SHA-256 checks; scheduler-gated destructive model delete.metal; legacyane/gpuvalues migrate; removed Cohere language picker; CLI still accepts--languageand saved Cohere language values (normalized, e.g. hi-IN → hi, ru-RU → ru) for compatibility but ignores them.metal/cpuwith legacy values accepted), and tests (stitching, lifecycle gates, scheduler deletion, Swift 6 isolation, bounded native waits).Dependencies
TranscribeCpppackage gated byMACPARAKEET_TRANSCRIBE_CPP_PACKAGE_PATH; production bundles a checksum-pinned arm64CTranscribe.frameworkand legal notices.transcribe.cppv0.1.3 (owned fork commit, wrapper version), and the GGUF model revision; verifier scripts fail closed on pin/provenance/architecture/artifact-tree drift; fail fast ifUNIVERSAL=1with the arm64-only artifact.Written for commit 1a38c0a. Summary will update on new commits.
Summary by CodeRabbit