From 7252406cd72afcbad3fa5079bc44b13ada9b79f8 Mon Sep 17 00:00:00 2001 From: baiqing Date: Sun, 9 Aug 2026 14:44:24 +0800 Subject: [PATCH 1/4] fix(release): keep publish checkout bytecode-free --- .github/workflows/release.yml | 1 + scripts/check_release_workflow.py | 5 ++++- scripts/test_check_release_workflow.py | 21 +++++++++++++++++++++ 3 files changed, 26 insertions(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 630a9d0a..7d6036e7 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -636,6 +636,7 @@ jobs: RELEASE_SHA: ${{ needs.validate.outputs.source_sha }} RELEASE_VERSION: ${{ needs.validate.outputs.version }} NOTES_PATH: ${{ needs.validate.outputs.notes_path }} + PYTHONDONTWRITEBYTECODE: '1' steps: - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4 with: diff --git a/scripts/check_release_workflow.py b/scripts/check_release_workflow.py index f9cdafa8..a69ce11c 100644 --- a/scripts/check_release_workflow.py +++ b/scripts/check_release_workflow.py @@ -190,7 +190,7 @@ "quality": "43599825f68088f3cc744220227267f77454e2c7ce389a52b8aee5a492491eec", "macos_arm64": "f913508e4f041614a967f680515cc0b8779800f0b2a7b4b6ff29f24f4bb1efd2", "windows_x64": "5f012278c20843ba1b38cffb27f3c614716bd92e3fec63a11885b41692be78b5", - "publish": "dd325630c78f236e972ca425ccc83018d12b4ec35a6b8a80d1af94990c8179a2", + "publish": "89192ac021d48cc8c8ef17b612a2da666d96c01d195c4e2b58eec24b2cc24d1b", } @@ -969,6 +969,9 @@ def validate_workflow(workflow: str) -> list[str]: return list(dict.fromkeys(errors)) if publish.get("permissions") != {"contents": "write"}: errors.append("publish-only contents write permission") + publish_env = _as_mapping(publish.get("env")) + if publish_env is None or publish_env.get("PYTHONDONTWRITEBYTECODE") != "1": + errors.append("publish Python helpers cannot write bytecode into the checkout") initialize_publish = _structured_step(publish, "Initialize isolated publish root") download_macos = _structured_step(publish, "Download macOS artifact") download_windows = _structured_step(publish, "Download Windows artifact") diff --git a/scripts/test_check_release_workflow.py b/scripts/test_check_release_workflow.py index 1beb6184..7c2198f0 100644 --- a/scripts/test_check_release_workflow.py +++ b/scripts/test_check_release_workflow.py @@ -334,6 +334,27 @@ def test_publish_outputs_must_stay_outside_the_worktree(self) -> None: ) self.assert_rejected(mutated, "publish outputs stay outside the worktree") + def test_publish_python_helpers_cannot_write_bytecode_into_checkout(self) -> None: + protected_env = " PYTHONDONTWRITEBYTECODE: '1'\n" + if protected_env in WORKFLOW: + protected = WORKFLOW + else: + protected = self.mutate( + " NOTES_PATH: ${{ needs.validate.outputs.notes_path }}\n", + " NOTES_PATH: ${{ needs.validate.outputs.notes_path }}\n" + + protected_env, + ) + unprotected = protected.replace(protected_env, "", 1) + + self.assertNotIn( + "publish Python helpers cannot write bytecode into the checkout", + contract.validate_workflow(protected), + ) + self.assert_rejected( + unprotected, + "publish Python helpers cannot write bytecode into the checkout", + ) + def test_macos_package_command_cannot_be_faked_by_an_echo_string(self) -> None: original = ( " run: >-\n" From 39651b39549d68d946aae6ba571ce5d860f97440 Mon Sep 17 00:00:00 2001 From: baiqing Date: Sun, 9 Aug 2026 21:34:13 +0800 Subject: [PATCH 2/4] fix(playback): harden source preview and Space transport --- docs/architecture/PLAYBACK-ENGINE.md | 24 ++ src-tauri/src/playback/commands.rs | 10 +- src-tauri/src/playback/project.rs | 141 ++++++++- src-tauri/src/render.rs | 60 +++- src-tauri/tests/playback_probe.rs | 74 +++-- web/src/components/media/MediaPanel.test.tsx | 4 +- .../preview/Preview.interaction.test.tsx | 159 +++++++++- web/src/components/preview/Preview.test.tsx | 46 +++ web/src/components/preview/Preview.tsx | 289 +++++++++++++++++- .../components/preview/RustFrameBuffer.tsx | 7 +- .../preview/nativePlaybackSession.test.ts | 84 +++++ .../preview/nativePlaybackSession.ts | 59 +++- web/src/hooks/useKeyboardShortcuts.test.ts | 91 +++++- web/src/hooks/useKeyboardShortcuts.ts | 32 +- web/src/lib/api.ts | 3 + 15 files changed, 1002 insertions(+), 81 deletions(-) diff --git a/docs/architecture/PLAYBACK-ENGINE.md b/docs/architecture/PLAYBACK-ENGINE.md index d7ecc36d..320bdc5e 100644 --- a/docs/architecture/PLAYBACK-ENGINE.md +++ b/docs/architecture/PLAYBACK-ENGINE.md @@ -32,6 +32,23 @@ surface. Reverse and positive-speed media can remain on this route when no compositor-only content is present. This route has no libmpv dependency or transparent native-player hole. +## Source-media preview route + +The source tab uses the Rust streaming engine whenever the packaged playback +capability is available. `playback_start(mediaId)` projects the selected video +into a private one-track timeline at the project fps, then reuses the same +FFmpeg RGBA decode, compositor, cpal audio clock, exact publication, and +identity-scoped pause/seek/stop lifecycle as timeline playback. The source +asset is read directly; this route does not create a whole-file proxy or +transcode by default. + +Paused source frames and paused seeks use `composite_frame(sourceMediaId)` so +they also decode through FFmpeg instead of switching back to WebKit. A terminal +frame remains painted, Play rewinds it to frame zero, and selecting another +asset retires the previous source session before accepting its publications. +The ordinary `