Skip to content

fix(editor): skip keyframe cache persistence when no workspace root (host-mounted) - #12

Merged
lightninglu10 merged 1 commit into
stagingfrom
fix/decoder-prewarm-workspace-gate
Aug 21, 2026
Merged

fix(editor): skip keyframe cache persistence when no workspace root (host-mounted)#12
lightninglu10 merged 1 commit into
stagingfrom
fix/decoder-prewarm-workspace-gate

Conversation

@lightninglu10

@lightninglu10 lightninglu10 commented Aug 21, 2026

Copy link
Copy Markdown

Defect

@quantfive/freecut-editor-surface@0.3.0: the decoder-prewarm worker's keyframes_extracted message handler (src/features/preview/utils/decoder-prewarm.ts) called updateMedia(mediaId, { keyframeTimestamps }) unconditionally. updateMedia() goes through requireWorkspaceRoot() (src/infrastructure/storage/workspace-fs/root.ts), which throws Workspace root is not set... when the editor surface is host-mounted without <WorkspaceGate> — as CodePress mounts it. The throw escaped the Worker onmessage handler on every play/pause cycle of decoded media (in dev, opening the blocking Next.js error overlay).

In-session keyframe registration (registerKeyframeIndex) was unaffected — only the workspace persistence path needs a root.

Fix

Gate the persistence call on getWorkspaceRoot() (already exported from the same module; returns null instead of throwing): when no workspace root is set, updateMedia is skipped. registerKeyframeIndex and keyframesSentForSrc.add remain unconditional, so the export/edit overlay path keeps working in host-mounted sessions; only cross-session keyframe persistence is skipped there.

Regression tests

Two new cases in src/features/preview/utils/decoder-prewarm.test.ts:

  • No workspace root: dispatching keyframes_extracted does not throw, still registers the in-session keyframe index, and never calls updateMedia.
  • Workspace root set: the same message still persists via updateMedia(mediaId, { keyframeTimestamps }).

Version bump

@quantfive/freecut-editor-surface 0.3.0 → 0.3.1 (patch: fail-soft behavior fix). Publish of 0.3.1 is intentionally not done in this PR — publishing stays manager/human-owned.

Gate results (at head 18d0581)

  • npm run check (typecheck+lint, 2439 files): pass
  • npm run lint: 1 error — typescript(TS2307) in packages/freecut-editor/consumer-smoke.test.tsx (cannot resolve @quantfive/freecut-editor-surface). Inherited: reproduces identically at base fedfb2d6 with changes stashed.
  • Focused tests: decoder-prewarm.test.ts 22/22 pass; src/infrastructure/storage 158/158 pass (19 files)
  • npm run build:editor-surface (package build): pass; npm run build (app build): pass
  • npm run check:boundaries, check:legacy-lib-imports, check:changed-health (0 introduced dead_code/complexity/duplication): pass
  • npm run verify:provenance (reproducible-package verify-only): pass
  • vp fmt --check on changed files: pass (repo-wide format:check flags 169 pre-existing files, unchanged by this PR)

…host-mounted)

The decoder-prewarm worker's keyframes_extracted handler called
updateMedia() unconditionally. updateMedia() goes through
requireWorkspaceRoot(), which throws when the editor surface is
host-mounted without <WorkspaceGate> (e.g. CodePress) — surfacing as
an uncaught error on every decoded play/pause cycle.

Gate the persistence call on getWorkspaceRoot(): host-mounted surfaces
skip cross-session keyframe persistence while in-session registration
(registerKeyframeIndex, keyframesSentForSrc) stays unconditional.

Bump @quantfive/freecut-editor-surface to 0.3.1 (fail-soft fix;
publish intentionally not done here).
@lightninglu10

Copy link
Copy Markdown
Author

@codepress /judge-verification can you judge this verification?

Local Verification

PR Head SHA: 18d0581ae41e3c93e49ea735457014aa97890183

Scope: FreeCut PR #12 (draft, base staging) — fail-soft fix for polish-pass defect D1: with the surface host-mounted (CodePress renders no <WorkspaceGate>), the decoder-prewarm worker's keyframes_extracted handler called updateMedia(...), whose storage layer throws Workspace root is not set — an uncaught page error on every play/pause of decoded media (in dev it opens the blocking Next.js overlay; in prod, uncaught error per play cycle and cross-session keyframe caching never worked). Fix: gate the persistence call on getWorkspaceRoot() (returns null instead of throwing); in-session registerKeyframeIndex/keyframesSentForSrc stay unconditional. Package version bumped 0.3.0 → 0.3.1 (not published — publish is human/manager-owned).

Diff Trigger Inventory

  • src/features/preview/utils/decoder-prewarm.tskeyframes_extracted handler gates updateMedia on getWorkspaceRoot(); comment documents the host-mounted case.
  • src/features/preview/utils/decoder-prewarm.test.ts — two regression cases: no root → dispatching keyframes_extracted does not throw, in-session index still registered, updateMedia never called; root set → updateMedia called with (mediaId, { keyframeTimestamps }).
  • packages/freecut-editor/package.json — version 0.3.0 → 0.3.1 only.

No CodePress-side changes in this PR; the CodePress bump is a separate follow-up lane.

Verification Contract Results

Re-run fresh at the head above by the manager (not just worker-reported), from the worktree /Users/lightninglu10/Q5/.worktrees/freecut/fix-decoder-prewarm-workspace-gate:

npx vitest run src/features/preview/utils/decoder-prewarm.test.ts
# Tests 22 passed (22) — incl. both new no-root/root-set regression cases
npx vitest run src/infrastructure/storage
# pass (158 tests, 19 files)
npm run check
# pass: Found no warnings, lint errors, or type errors in 2439 files
npm run build:editor-surface
# ✓ built (14m10s on a heavily loaded machine) — package artifact builds at 0.3.1

Worker-reported at the same head (spot-verified consistent with the runs above): check:boundaries, check:legacy-lib-imports, check:changed-health (0 introduced), verify:provenance, vp fmt --check on changed files — all pass.

Inherited base failures (reproduced at base fedfb2d6 by the worker, not touched by this diff): npm run lint TS2307 consumer-smoke module resolution; repo-wide format:check flags 169 pre-existing files (changed files clean). Full jsdom suite not run (known Node 26 localStorage storm, pre-existing).

Post-verification captures: git rev-parse HEAD = 18d0581ae41e3c93e49ea735457014aa97890183; git status --porcelain empty. GitHub PR #12 headRefOid matches.

Overall: PASS

The D1 defect is fixed fail-soft with red/green-capable regression coverage (the no-root case throws before the fix by construction of requireWorkspaceRoot); focused tests, storage suite, repo check, and the package build are all green at this head with a clean tree.

@codepress-dev

codepress-dev Bot commented Aug 21, 2026

Copy link
Copy Markdown

👋 Hey @lightninglu10! Spawning a verification judge session to help with your request. View session

@codepress-dev

codepress-dev Bot commented Aug 21, 2026

Copy link
Copy Markdown

@Terminal @lightninglu10

Dispatched by judge-verification.

This judgment is READY TO MERGE at the current head. If the PR is still a draft, transition it to ready for review now with the guarded readiness transaction: codepress-policy ready-for-review --repo . --pr 12 (or node packages/delivery-policy/dist/cli.js ready-for-review --repo . --pr 12 when the CLI is not on PATH). It re-validates current-head QA and judge evidence, reconciles the delivery-status marker, and marks the PR ready so the native reviewer can dispatch. Do not call gh pr ready directly, and do not merge; merge authorization still requires the reviewer gate.

Verification Judgment — PR #12 (local)

Verdict: ✅ READY TO MERGE

PR Head SHA: 18d0581ae41e3c93e49ea735457014aa97890183

Summary: The current PR head is safe to merge. The three-file diff gates only the cross-session updateMedia write when a workspace root is available, while retaining in-session keyframe registration. The focused regression cases cover both no-root and root-set branches, the storage suite and repository check are reported green, and the editor-surface build produces version 0.3.1.

Revision binding

  • Classification: SAME-SHA LATE BINDING
  • Report head: 18d0581ae41e3c93e49ea735457014aa97890183
  • Live PR head: 18d0581ae41e3c93e49ea735457014aa97890183
  • Audited checkout: clean detached checkout at 18d0581ae41e3c93e49ea735457014aa97890183
  • Concrete evidence: gh pr view returned headRefOid=18d0581ae41e3c93e49ea735457014aa97890183; in the detached audit checkout, git rev-parse HEAD -> 18d0581ae41e3c93e49ea735457014aa97890183; git status --porcelain -> (empty). The live diff from base fedfb2d6b1e5ec619b6a42e1e7ab8b8ba363b9cc contains exactly packages/freecut-editor/package.json, src/features/preview/utils/decoder-prewarm.test.ts, and src/features/preview/utils/decoder-prewarm.ts; git diff --check is clean. The report independently records the same git rev-parse HEAD value and an empty git status --porcelain result.
  • Rows carried forward: none
  • Rows reverified at live head: none
  • Rows still requiring verification: none
  • Publication timing: The canonical report comment was created at 2026-08-21T20:24:20Z and names the same SHA returned by the live PR-head query; no head mismatch is present.

Diff trigger inventory

Surface Location Coverage
Host-mounted keyframes_extracted handling remains fail-soft and keeps in-session registration src/features/preview/utils/decoder-prewarm.ts:228-240 1
Workspace-backed persistence remains enabled with the expected media ID and timestamps src/features/preview/utils/decoder-prewarm.ts:237-240; src/features/preview/utils/decoder-prewarm.test.ts:752-769 2
Editor-surface package version metadata changes from 0.3.0 to 0.3.1 packages/freecut-editor/package.json:2-3 3

Per-item

# Verifier said Judgment Evidence
1 PASS ✅ PASS The report's manager rerun records npx vitest run src/features/preview/utils/decoder-prewarm.test.ts with 22/22 passing, including the no-root case. The audited code registers the keyframe index before checking the root, and getWorkspaceRoot() returns null without a gate; the no-root test asserts no throw, preserved in-session timestamps, and no updateMedia call. The storage implementation requires a root at entry, so omitting that call removes the reported host-mounted failure path.
2 PASS ✅ PASS The same focused suite records the root-set regression passing. The root-backed test dispatches keyframes_extracted, verifies in-session timestamps, and verifies updateMedia('media-persisted', { keyframeTimestamps: [0, 2] }); the handler's root guard preserves this branch.
3 PASS ✅ PASS The report records npm run build:editor-surface passing with the package artifact at 0.3.1. The audited diff changes only the package version field, with no unrelated package or runtime changes.

Overall status check

  • Verifier said: PASS
  • Result: READY TO MERGE

What stood up

  • The report is bound to the live PR head and includes verifier-side head and cleanliness captures.
  • The actual diff matches the declared inventory and has no additional graph-mandated verification surface; this checkout contains neither codepress_documentation/verification/GRAPH.md nor scripts/verification-checks.sh.
  • The focused decoder-prewarm suite, storage suite, repository check, and editor-surface build provide coherent evidence for the changed branches and package metadata.

@lightninglu10
lightninglu10 marked this pull request as ready for review August 21, 2026 20:31
@codepress-reviewer-dev

Copy link
Copy Markdown

Starting initial review of 18d0581a from baseline fedfb2d6... 👀

View automation run

@codepress-reviewer-dev codepress-reviewer-dev Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Approved. The change cleanly treats workspace persistence as optional for host-mounted editor surfaces while preserving the in-session keyframe index used by preview/export behavior.

The two regression cases cover the relevant branches: no workspace root does not call storage or throw, and a configured root still calls updateMedia with the extracted timestamps. This is a cohesive patch-level fix with no actionable concerns found.

Reviewed `fedfb2d6`...`18d0581a`. Diff collection and GitHub posting were handled by the automation.

View automation run

@codepress-reviewer-dev

Copy link
Copy Markdown

Review head 18d0581ae41e3c93e49ea735457014aa97890183; round 1; 3 reviewed file(s), 0 pending/skipped file(s). 0 subsystem record(s) retained; 0 omitted.

View automation run

@lightninglu10
lightninglu10 merged commit a188efa into staging Aug 21, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant