Skip to content

Phase 1 Wave 3: AppImage launcher + .deb ffprobe + Docker LAN + Gatekeeper probe (closes #54, #56, #76, #80)#93

Merged
debpalash merged 4 commits into
mainfrom
phase-1-wave-3-bundler-launcher-fixes
May 20, 2026
Merged

Phase 1 Wave 3: AppImage launcher + .deb ffprobe + Docker LAN + Gatekeeper probe (closes #54, #56, #76, #80)#93
debpalash merged 4 commits into
mainfrom
phase-1-wave-3-bundler-launcher-fixes

Conversation

@debpalash

@debpalash debpalash commented May 20, 2026

Copy link
Copy Markdown
Owner

Summary

Phase 1 Wave 3 of the v0.3.0 stabilization milestone. Lands four issue-bound fixes plus the macOS Gatekeeper backend detection wiring that Wave 2's React ErrorBoundary consumes.

  • [Bug] AppImage on Fedora 44 doesn't start - white screen #56 — AppImage Fedora white-screen. New frontend/src-tauri/appimage/AppRun conditionally sets WEBKIT_DISABLE_COMPOSITING_MODE=1 only on broken WebKit ranges (2.44.x / 2.46.x / unknown), injected into Tauri's bundler via a beforeBundleCommand hook. Spike outcome documented in .planning/decisions/apprun-strategy.md.
  • Install error / deb package on Ubuntu 26.04 / trying to overwrite ffprobe #76 — .deb ffprobe conflict on Ubuntu 26.04. Bundled ffprobe moves to /usr/lib/omnivoice-studio/bin/ffprobe via bundle.linux.deb.files. Defensive postinst removes any legacy /usr/bin/ffprobe only when dpkg -S confirms our package owns it. Backend resolves through OMNIVOICE_FFPROBE_PATH (canonical) with FFPROBE_PATH retained as a legacy alias.
  • [Bug] Unable to use pre-built Docker image when not using localhost #80 — Docker LAN frontend. New frontend/src/utils/apiBase.ts follows window.location.hostname:3900 in plain-browser contexts so LAN clients hit the OmniVoice host, not their own loopback. Tauri webview unchanged. Single hardcode site (media.js:20) confirmed by grep sweep.
  • [Bug] .dmg install on macOS Sequoia fails #54 — macOS Gatekeeper. New backend/core/gatekeeper_detect.py runs xattr -l against the resolved .app bundle at lifespan startup; on detection it logs a structured warning and emits error_class="GATEKEEPER_QUARANTINE" via the existing event bus for the Wave 2 deeplink. Detection only — never auto-runs xattr -cr.
  • INST-01 (no-regression). New tests/backend/test_pyproject.py guards the setuptools>=75.0 pin from PR fix: setuptools pin, Linux/Russia troubleshooting (#58, #56, #60) #62. Smoke test gains an inline pkg_resources + whisperx import probe.

Test plan

  • uv run pytest tests/backend/services/test_ffmpeg_utils.py tests/backend/core/test_gatekeeper_detect.py tests/backend/test_pyproject.py -x -v14/14 pass
  • bash frontend/src-tauri/appimage/AppRun.test.sh4/4 pass (per checker W-1: 2.44 broken, 2.46 broken, 2.48 healthy, pkg-config absent)
  • cd frontend && bun run test apiBase6/6 pass
  • cd frontend && bun run test (all) → 30/30 pass (no regressions)
  • grep -rnE '(localhost|127\.0\.0\.1):3900' frontend/src/ → only comment lines remain
  • uv run pytest tests/ -q (full backend) → 292 passed, 6 skipped, 12 xfailed, 1 xpassed (no failures)
  • Manual: launch a debug .deb build on a Linux VM, confirm /usr/lib/omnivoice-studio/bin/ffprobe exists and backend reads it via OMNIVOICE_FFPROBE_PATH.
  • Manual: launch the macOS .app from /Applications, confirm that with xattr -l showing quarantine, the startup probe surfaces the error class.
  • Manual: Phase 6 / GATE-03 release.yml smoke runs the full AppImage build and verifies the injected AppRun.

Closures

Decision docs

  • .planning/decisions/apprun-strategy.md — AppRun strategy spike outcome
  • .planning/phases/01-install-token-persistence-docs-scaffolding-error-ux/01-03-SUMMARY.md — full wave summary

Deviations from plan

  1. AppRun spike was code-inspected + documented from Tauri 2 public docs rather than from a live cargo tauri build (the build requires Linux). The decision doc calls this out — Phase 6 release.yml smoke validates the injected AppRun end-to-end.
  2. FFPROBE_PATH env var kept alongside the canonical OMNIVOICE_FFPROBE_PATH for backward compat with prior backend builds and external scripts.
  3. apiBase.ts exposes a small _setEnvOverrideForTesting() hook because vitest 4.x does not propagate vi.stubEnv to dynamically imported modules' import.meta.env. Production code path unchanged.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • macOS Gatekeeper quarantine detection with user-facing error reporting
    • Centralized API endpoint configuration system
  • Bug Fixes

    • Fixed AppImage display issues using WebKitGTK compositor workaround
    • Improved bundled binary handling on Linux packages
  • Tests

    • Added comprehensive test coverage for quarantine detection and API configuration

Review Change Stack

debpalash and others added 4 commits May 20, 2026 05:41
)

WebKitGTK 2.44.x and 2.46.x have a compositing-path regression on Wayland
that blanks the AppImage's first paint on Fedora 44 / Ubuntu 24.04. Setting
WEBKIT_DISABLE_COMPOSITING_MODE=1 forces the software fallback that works,
but blindly setting it on healthy WebKit versions (2.48+) regresses those.

This wave adds a conditional AppRun launcher that detects the WebKit
version via pkg-config and only sets the env var on the broken ranges
(plus a fail-safe when pkg-config is absent or the version is unknown).
The launcher is injected into Tauri's AppImage staging dir via a
beforeBundleCommand hook — see .planning/decisions/apprun-strategy.md for
the spike outcome and rationale (Strategy B chosen).

Phase 1 Wave 3 — Plan 01-03 Task 1. Closes #56 frontend half.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…#76)

Prior versions placed the bundled ffprobe at /usr/bin/ffprobe via Tauri's
externalBin, which overwrites the system ffprobe on Ubuntu 26.04 and
collides with apt-installed media-package ffprobe.

Relocate the .deb-bundled ffprobe to /usr/lib/omnivoice-studio/bin/ffprobe
via bundle.linux.deb.files, plus defensive maintainer scripts:
  - preinst:  ensure target dir exists for upgrade flows
  - postinst: remove legacy /usr/bin/ffprobe ONLY when dpkg confirms our
              package owns it (never touches a user's distro ffprobe)
  - postrm:   clean up the relocated path tree on purge/remove

Rust side (tools.rs::resolve_ffprobe) now probes the new path on Linux,
and backend spawn (backend.rs) carries both FFPROBE_PATH (legacy alias)
and OMNIVOICE_FFPROBE_PATH (canonical) into the backend env. Python side
(ffmpeg_utils.resolve_ffprobe) reads OMNIVOICE_FFPROBE_PATH first, falls
back to FFPROBE_PATH, then to shutil.which("ffprobe").

6 new unit tests cover the env-cascade resolution.

Phase 1 Wave 3 — Plan 01-03 Task 2. Closes #76.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Docker / LAN browser users hit the preview API at the LAN host's IP, not
their local machine — the prior frontend/src/utils/media.js:20 hardcoded
http://localhost:3900, which from a LAN client resolved to the client
machine itself.

Centralise via frontend/src/utils/apiBase.ts:
  1. VITE_OMNIVOICE_API override (Docker compose / dev) always wins.
  2. Tauri webview → http://localhost:3900 (unchanged behaviour).
  3. Plain browser → ${window.location.protocol}//${window.location.hostname}:3900
     (follows the page's origin — closes #80).
  4. SSR / no-window → http://localhost:3900 (safe fallback).

Grep-sweep confirmed media.js:20 was the only hardcode site (Assumption
A4 in 01-RESEARCH.md verified). 6 new vitest cases cover the resolver.

Phase 1 Wave 3 — Plan 01-03 Task 3. Closes #80 frontend half.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds backend/core/gatekeeper_detect.py which walks up from sys.executable
to find the .app bundle and runs `xattr -l` to check for the quarantine
extended attribute (com.apple.quarantine). On detection, the lifespan
startup probe logs a structured warning and emits a system_error event
through the existing event bus with error_class="GATEKEEPER_QUARANTINE",
which Wave 2's React ErrorBoundary turns into a docs deeplink.

Detection is informational only — we never auto-run `xattr -cr` (the app
itself is quarantined and cannot fix its own state per Anti-Pattern in
01-RESEARCH.md). Users get a clear pointer to the workaround docs.

GET /system/quarantine-status exposes the structured payload so the
frontend can poll on first load.

INST-01 (setuptools>=75.0 pin from PR #62) gains a PR-time guard in
tests/backend/test_pyproject.py + a user-observable smoke check in
scripts/smoke-test.sh (pkg_resources + whisperx import).

7 gatekeeper tests + 1 pyproject test added — all pass.

Phase 1 Wave 3 — Plan 01-03 Task 4. Closes #54 backend half (Wave 2 owns
the docs page + ErrorBoundary deeplink wiring).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented May 20, 2026

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

This PR ships Phase 1 Wave 3 completions: a custom AppImage AppRun launcher with WebKitGTK workarounds, Linux .deb ffprobe relocation with maintainer scripts, centralized frontend API base URL resolution, macOS Gatekeeper quarantine detection with REST endpoint and startup logging, plus comprehensive test coverage and phase documentation.

Changes

Phase 1 Wave 3: Multi-feature implementation

Layer / File(s) Summary
AppImage AppRun launcher strategy and injection
.planning/decisions/apprun-strategy.md, frontend/src-tauri/appimage/AppRun, frontend/src-tauri/appimage/AppRun.test.sh, scripts/inject-apprun.sh, frontend/src-tauri/tauri.conf.json
Decision document, custom launcher script with WebKitGTK version detection via pkg-config, Bash test harness validating compositor mode toggling, and beforeBundleCommand hook wiring to inject the launcher into AppImage staging before bundling.
Linux .deb ffprobe relocation
backend/services/ffmpeg_utils.py, frontend/src-tauri/src/backend.rs, frontend/src-tauri/src/tools.rs, frontend/src-tauri/tauri.linux.conf.json, frontend/src-tauri/debian/preinst, frontend/src-tauri/debian/postinst, frontend/src-tauri/debian/postrm
New resolve_ffprobe() function cascading through namespaced OMNIVOICE_FFPROBE_PATH, legacy FFPROBE_PATH, and PATH; Rust wiring to set both env vars; Linux Tauri config mapping to install /usr/lib/omnivoice-studio/bin/ffprobe; and Debian package lifecycle scripts for pre-install dir creation, post-install chmod, and ownership-aware cleanup on removal.
Frontend API base URL centralization
frontend/src/utils/apiBase.ts, frontend/src/utils/apiBase.test.ts, frontend/src/utils/media.js
New utility module resolving API base across test override, Tauri, browser, and SSR contexts with port 3900 hardcoding; comprehensive Vitest suite testing all four paths; integration into media.js to use shared resolver for preview endpoint.
macOS Gatekeeper quarantine detection
backend/core/gatekeeper_detect.py, backend/api/routers/system.py, backend/main.py, tests/backend/core/test_gatekeeper_detect.py
New detection module resolving .app bundle path and probing com.apple.quarantine via xattr with safe non-macOS defaults; loopback-gated REST endpoint /system/quarantine-status; startup logging and system_error event emission; pytest suite covering platforms, error modes, and payload contracts.
Test infrastructure and verification
tests/backend/services/test_ffmpeg_utils.py, tests/backend/test_pyproject.py, scripts/smoke-test.sh
Pytest suite validating resolve_ffprobe() env var precedence and fallback paths with stubbed shutil; setuptools >= 75.0 pin verification; smoke-test additions for quarantine endpoint and INST-01 dependency imports.
Phase 1 Wave 3 summary
.planning/phases/01-install-token-persistence-docs-scaffolding-error-ux/01-03-SUMMARY.md
Phase metadata, enumerated shipped features, test result table, grep-sweep confirmation of :3900 references, documented deviations (legacy env alias retained, vitest test-only workaround), and Phase 6 verification paths for Tauri config JSON keys.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • debpalash/OmniVoice-Studio#84: Adds require_loopback middleware to the entire /system/* router, which will govern access control for the newly added /system/quarantine-status endpoint in this PR.
  • debpalash/OmniVoice-Studio#27: Introduces the event_bus and WebSocket streaming at /ws/events, which this PR consumes in backend/main.py to emit "system_error" events when Gatekeeper quarantine is detected.

Poem

🐰 A bundled AppRun hops through the code,
ffprobe treads a LAN-bound road,
URLs dance from base to base,
Gatekeeper's seal set in its place—
Four paths converge, Phase One complete with grace!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 76.19% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main changes: Phase 1 Wave 3 implementation with four specific issue closures (#54, #56, #76, #80). It directly reflects the primary changeset focus.
Description check ✅ Passed The description includes all required template sections: Summary, Changes (with bullet points for each issue), Type (New feature + Tests), Testing (with specific test results), Checklist items, and Decision docs. All critical context is present.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch phase-1-wave-3-bundler-launcher-fixes

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🤖 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
@.planning/phases/01-install-token-persistence-docs-scaffolding-error-ux/01-03-SUMMARY.md:
- Around line 152-156: The fenced code block containing the grep command
"(localhost|127\.0\.0\.1):3900' frontend/src/" needs a language tag to satisfy
markdownlint MD040—edit the opening fence to "```bash" (i.e., add bash after the
three backticks) for the block that includes the grep pipeline and the
frontend/src/utils/media.js comment.

In `@backend/core/gatekeeper_detect.py`:
- Around line 89-90: The subprocess.run call that invokes "xattr" in
backend/core/gatekeeper_detect.py is vulnerable to PATH hijack; change the
invocation to use an absolute path (e.g. "/usr/bin/xattr") or resolve and
validate the binary once with shutil.which before calling subprocess.run (update
the call that builds ["xattr", "-l", bundle] to use the resolved path), and
handle the case where the binary is not found by logging or raising an error.

In `@backend/services/ffmpeg_utils.py`:
- Line 99: The current assignment candidate = ffmpeg_path.replace("ffmpeg",
"ffprobe") can mangle directory names; instead compute the probe path using
path-aware operations: locate the ffmpeg executable name (ffmpeg) and replace
only that basename with "ffprobe" (e.g., use
pathlib.Path(ffmpeg_path).with_name("ffprobe") or
os.path.join(os.path.dirname(ffmpeg_path), "ffprobe")) so directories containing
"ffmpeg" are not modified; update the code where candidate is set to use this
path-safe replacement (ffmpeg_path variable).

In `@scripts/smoke-test.sh`:
- Around line 327-330: The INST-01 import check currently uses "uv run python"
which may target a different environment; change the probe to invoke the
app-managed Python binary (the runtime/venv created during bootstrap) instead of
"uv run python" so the import test runs inside the actual app runtime. Replace
the "uv run python -c \"import pkg_resources; import whisperx\"" call with the
bootstrap-created runtime Python variable (e.g., the script's APP_PYTHON or
VENV_PYTHON) and keep the same pass/fail messages ("INST-01: ..." and "INST-01
regression: ...") so the check validates the launched app environment rather
than uv's environment.
🪄 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: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: d5abd337-4e23-4734-b88f-89fc1be15159

📥 Commits

Reviewing files that changed from the base of the PR and between a32828e and 200a91b.

📒 Files selected for processing (23)
  • .planning/decisions/apprun-strategy.md
  • .planning/phases/01-install-token-persistence-docs-scaffolding-error-ux/01-03-SUMMARY.md
  • backend/api/routers/system.py
  • backend/core/gatekeeper_detect.py
  • backend/main.py
  • backend/services/ffmpeg_utils.py
  • frontend/src-tauri/appimage/AppRun
  • frontend/src-tauri/appimage/AppRun.test.sh
  • frontend/src-tauri/debian/postinst
  • frontend/src-tauri/debian/postrm
  • frontend/src-tauri/debian/preinst
  • frontend/src-tauri/src/backend.rs
  • frontend/src-tauri/src/tools.rs
  • frontend/src-tauri/tauri.conf.json
  • frontend/src-tauri/tauri.linux.conf.json
  • frontend/src/utils/apiBase.test.ts
  • frontend/src/utils/apiBase.ts
  • frontend/src/utils/media.js
  • scripts/inject-apprun.sh
  • scripts/smoke-test.sh
  • tests/backend/core/test_gatekeeper_detect.py
  • tests/backend/services/test_ffmpeg_utils.py
  • tests/backend/test_pyproject.py

Comment on lines +152 to +156
```
$ grep -rnE '(localhost|127\.0\.0\.1):3900' frontend/src/ \
--include='*.{js,jsx,ts,tsx}' | grep -v apiBase.ts | grep -v apiBase.test.ts
frontend/src/utils/media.js:21:// (issue #80) get window.location.hostname:3900 instead of localhost:3900.
```

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Specify a language for the fenced code block.

Line 152 opens a fence without a language, which triggers markdownlint MD040. Mark it as bash since it contains shell commands.

Suggested fix
-```
+```bash
 $ grep -rnE '(localhost|127\.0\.0\.1):3900' frontend/src/ \
     --include='*.{js,jsx,ts,tsx}' | grep -v apiBase.ts | grep -v apiBase.test.ts
 frontend/src/utils/media.js:21:// (issue `#80`) get window.location.hostname:3900 instead of localhost:3900.
</details>

<!-- suggestion_start -->

<details>
<summary>📝 Committable suggestion</summary>

> ‼️ **IMPORTANT**
> Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

```suggestion

🧰 Tools
🪛 markdownlint-cli2 (0.22.1)

[warning] 152-152: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

🤖 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
@.planning/phases/01-install-token-persistence-docs-scaffolding-error-ux/01-03-SUMMARY.md
around lines 152 - 156, The fenced code block containing the grep command
"(localhost|127\.0\.0\.1):3900' frontend/src/" needs a language tag to satisfy
markdownlint MD040—edit the opening fence to "```bash" (i.e., add bash after the
three backticks) for the block that includes the grep pipeline and the
frontend/src/utils/media.js comment.

Comment on lines +89 to +90
result = subprocess.run(
["xattr", "-l", bundle],

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Use an absolute xattr path to avoid PATH hijack risk.

At Line 89, spawning "xattr" via PATH can execute an unexpected binary if PATH is manipulated. Prefer /usr/bin/xattr (or resolve once via shutil.which and validate).

Suggested patch
@@
-import subprocess
+import shutil
+import subprocess
@@
-        result = subprocess.run(
-            ["xattr", "-l", bundle],
+        xattr_bin = shutil.which("xattr") or "/usr/bin/xattr"
+        result = subprocess.run(
+            [xattr_bin, "-l", bundle],
             capture_output=True,
             text=True,
             timeout=5,
             check=False,
         )
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
result = subprocess.run(
["xattr", "-l", bundle],
import shutil
import subprocess
xattr_bin = shutil.which("xattr") or "/usr/bin/xattr"
result = subprocess.run(
[xattr_bin, "-l", bundle],
capture_output=True,
text=True,
timeout=5,
check=False,
)
🧰 Tools
🪛 Ruff (0.15.13)

[error] 89-89: subprocess call: check for execution of untrusted input

(S603)


[error] 90-90: Starting a process with a partial executable path

(S607)

🤖 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 `@backend/core/gatekeeper_detect.py` around lines 89 - 90, The subprocess.run
call that invokes "xattr" in backend/core/gatekeeper_detect.py is vulnerable to
PATH hijack; change the invocation to use an absolute path (e.g.
"/usr/bin/xattr") or resolve and validate the binary once with shutil.which
before calling subprocess.run (update the call that builds ["xattr", "-l",
bundle] to use the resolved path), and handle the case where the binary is not
found by logging or raising an error.

if os.path.isfile(candidate):
return candidate
if ffmpeg_path:
candidate = ffmpeg_path.replace("ffmpeg", "ffprobe")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Use path-aware replacement to avoid corrupting directory names.

The string replace("ffmpeg", "ffprobe") will incorrectly transform paths where "ffmpeg" appears in a directory name (e.g., /opt/ffmpeg/bin/ffmpeg/opt/ffprobe/bin/ffprobe).

🛠️ Proposed fix using path manipulation
         ffmpeg_path = find_ffmpeg()
         if ffmpeg_path:
-            candidate = ffmpeg_path.replace("ffmpeg", "ffprobe")
+            parent = os.path.dirname(ffmpeg_path)
+            basename = os.path.basename(ffmpeg_path)
+            candidate = os.path.join(parent, basename.replace("ffmpeg", "ffprobe"))
             if os.path.isfile(candidate):
                 return candidate
🤖 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 `@backend/services/ffmpeg_utils.py` at line 99, The current assignment
candidate = ffmpeg_path.replace("ffmpeg", "ffprobe") can mangle directory names;
instead compute the probe path using path-aware operations: locate the ffmpeg
executable name (ffmpeg) and replace only that basename with "ffprobe" (e.g.,
use pathlib.Path(ffmpeg_path).with_name("ffprobe") or
os.path.join(os.path.dirname(ffmpeg_path), "ffprobe")) so directories containing
"ffmpeg" are not modified; update the code where candidate is set to use this
path-safe replacement (ffmpeg_path variable).

Comment thread scripts/smoke-test.sh
Comment on lines +327 to +330
if uv run python -c "import pkg_resources; import whisperx" 2>/dev/null; then
pass "INST-01: pkg_resources + whisperx import OK (setuptools pinned)"
else
fail "INST-01 regression: pkg_resources or whisperx import failed (setuptools pin?)"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Run INST-01 import check against the launched app runtime, not uv run.

At Line 327, uv run can validate a different environment than the app process used in this smoke test, causing false confidence or false failures. Point the import check at the app-managed Python/venv path created during bootstrap.

Suggested patch
 TESTS=$((TESTS + 1))
-if uv run python -c "import pkg_resources; import whisperx" 2>/dev/null; then
+APP_PY="${OV_DATA}/.venv/bin/python"
+if [ -x "$APP_PY" ] && "$APP_PY" -c "import pkg_resources; import whisperx" 2>/dev/null; then
     pass "INST-01: pkg_resources + whisperx import OK (setuptools pinned)"
 else
-    fail "INST-01 regression: pkg_resources or whisperx import failed (setuptools pin?)"
+    fail "INST-01 regression: app runtime import failed (pkg_resources or whisperx)"
 fi
🤖 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 `@scripts/smoke-test.sh` around lines 327 - 330, The INST-01 import check
currently uses "uv run python" which may target a different environment; change
the probe to invoke the app-managed Python binary (the runtime/venv created
during bootstrap) instead of "uv run python" so the import test runs inside the
actual app runtime. Replace the "uv run python -c \"import pkg_resources; import
whisperx\"" call with the bootstrap-created runtime Python variable (e.g., the
script's APP_PYTHON or VENV_PYTHON) and keep the same pass/fail messages
("INST-01: ..." and "INST-01 regression: ...") so the check validates the
launched app environment rather than uv's environment.

@debpalash debpalash merged commit c320412 into main May 20, 2026
8 checks passed
@debpalash debpalash deleted the phase-1-wave-3-bundler-launcher-fixes branch June 12, 2026 10:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant