Uh oh!
There was an error while loading. Please reload this page.
[codepress#5858 3a] ripple_delete capability, transcript cut, requestTranscription - #17
Conversation
…ription `ripple_delete` is a real EditCommand with a working engine implementation, but `capabilityForCommand` returned null for it, so `controller.submitEdit` rejected any transcript cut batch as unsupported before it reached the host. Map it onto `timeline.remove` and add it to `SUPPORTED_HOST_COMMANDS`. The host transcript editor hardcoded `action: 'captions'`, so captions were the only thing the UI could emit. Un-hardcode the preview action and add a "Cut selection" affordance that reuses the same preview -> submitEdit path with `action: 'cut'` (the normalized action the CodePress adapter turns into `ripple_delete` commands). Add the optional `EditorTranscriptPort.requestTranscription` and a "Transcribe" affordance in the not-yet-succeeded branch, which polls `getStatus` until the receipt is terminal. The poll interval and attempt cap read from `VITE_HOST_TRANSCRIBE_POLL_MS` / `VITE_HOST_TRANSCRIBE_POLL_MAX_ATTEMPTS` with the production values as defaults.
lightninglu10
commented
Aug 22, 2026
Canonical QA ReportVerifier revision bindingbase: 47e2db3 (origin/staging) Note: this PR is stacked — its PR base is Gate results
Also run: Inherited baseline failures
Environment blockers
Visual / browser artifacts
Overall✅ PASS — PENDING JUDGE (Gates 4, 10, 11 are disclosed inherited baseline failures reproduced at the stack base; no new failure is introduced by this PR.) No merge until trusted judge PASS. |
lightninglu10
commented
Aug 22, 2026
@codepress /judge-verification can you judge this verification? |
👋 Hey @lightninglu10! Spawning a verification judge session to help with your request. View session |
Dispatched by judge-verification. Work the Path to merge below. Reuse healthy exact-head verification environments; do not redeploy or restart unless stale or unhealthy. Continue only when there is meaningful work to clear the blocker. If the path is already satisfied, the same blocker remains, or another judge pass would add no useful evidence, stop and report that instead of submitting another verification report. Verification Judgment — PR #17 (local)Verdict: ❌ NOT READY TO MERGE PR Head SHA: Summary: The canonical report is bound to the live PR head and records a clean verifier checkout. Its deterministic evidence supports the new Revision binding
Diff trigger inventory
Per-item
Overall status check
Path to merge
Becomes Dispatch: yes What stood up
|
#15 publishes 0.3.3 when it merges, and the OIDC publish workflow's already-published guard refuses a second publish at the same version. This PR therefore has to carry its own version for its surface changes (the ripple_delete capability, the transcript cut action, and the optional requestTranscription port) to reach the registry.
lightninglu10
commented
Aug 22, 2026
@codepress /judge-verification can you judge this verification? Local VerificationPR Head SHA:
Verifier revision binding
Captured from Diff Trigger Inventory
Verification Contract ResultsHow G1/G2/G3 were exercised. Negative control (anti-vacuity). The identical consumer app and identical
Rows 15–17 are the three disclosed failures, recorded as failures per Evidence artifacts. Screenshots, the per-check results, and the negative-control Scope note. The published bundle inlines Overall: PASS |
👋 Hey @lightninglu10! Spawning a verification judge session to help with your request. View session |
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: Verification Judgment — PR #17 (local)Verdict: ✅ READY TO MERGE PR Head SHA: Summary: The report is bound to the live PR head, the verifier captured a clean checkout, and feature-specific live checks against the packed 0.3.4 artifact establish the transcript cut, capability gate, host transcription request, polling, and terminal-state behavior. The three disclosed suite/ratchet failures reproduce at the stack base and are immaterial to the inventoried change. Revision binding
Diff trigger inventory
Per-item
Overall status check
What stood up
|
Starting initial review of |
There was a problem hiding this comment.
Request changes: the host-preview boundary needs one more semantic check before this enables a destructive command.
previewSelection records the action the user chose, but it accepts any capability-enabled command batch returned by the host. A captions request that mistakenly returns a ripple_delete batch now passes commandIsSupported, is shown as “Apply captions,” and can remove timeline content when applied. Previously that bad response was stopped because ripple_delete was unsupported.
Please reject previews whose normalized returned action or command family does not match the requested action before storing them as a preview, and add a regression test for that mismatched captions response. The existing host-owned preview → explicit apply shape otherwise remains appropriate.
Reviewed `aca96133`...`63bad2b6`. Diff collection and GitHub posting were handled by the automation.Review head |
… for previewSelection recorded the requested action but then accepted any batch the host returned as long as every command was capability-enabled. Making ripple_delete capability-enabled removed the fail-closed behavior that used to stop a mismatched batch: a captions request answered with a ripple_delete batch now passed commandIsSupported, was labeled "Apply captions", and deleted timeline content when applied. Reject a preview before it is stored unless it matches the requested action -- the echoed action, when the host sends one, and every command in the batch against that action's command family (ripple_delete for cut, caption commands for captions). A mismatch surfaces as a non-retryable transcript_preview_action_mismatch validation error, so no preview is stored and there is nothing to apply.
Starting new changes review of |
There was a problem hiding this comment.
The preview/apply boundary now has the missing semantic check: the surface normalizes the requested and echoed actions, constrains each action to its allowed command family, and rejects a mismatch before storing a preview. The added regression cases cover the captions-to-ripple-delete path, the inverse command-family mismatch, and an incorrect action echo. This keeps preview creation with the host while ensuring the UI never labels a destructive batch as captions.
Approved with one nonblocking follow-up:
- Warning —
src/features/editor/host/transcript-editor.tsx:846: polling is not cancelled when the Transcript component unmounts. Switching away from the real Transcript tab unmounts this component, but an active request can continue callinggetStatus()for up to 200 attempts. Invalidate the generation in unmount cleanup (and preferably cancel the outstanding delay), with a test that confirms polling stops after unmount.
lightninglu10
commented
Aug 22, 2026
@codepress /judge-verification can you judge this verification? Local VerificationPR Head SHA:
Verifier revision binding
Diff Trigger Inventory
Verification Contract ResultsHow G1/G2/G3/G4 were exercised. Negative control (anti-vacuity). The identical consumer app and identical host
Rows 15–17 are the three disclosed failures, recorded as failures per Evidence artifacts. 12 screenshots (all digests distinct — checked for Scope note. The published bundle inlines Known non-blocking follow-up. The reviewer's approval carried one non-blocking Overall: PASS |
👋 Hey @lightninglu10! Spawning a verification judge session to help with your request. View session |
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: Verification Judgment — PR #17 (local)Verdict: ✅ READY TO MERGE PR Head SHA: Summary: The report is bound to the live PR head, the verifier captured a clean checkout, and the packed 0.3.4 surface was exercised through the real Transcript UI and caller-supplied host port. The live observations establish transcript cut preview/apply behavior, ripple deletion and capability denial, transcription start/polling/terminal handling, and the reviewer-finding regression guard. The three disclosed suite and ratchet failures reproduce at the stack base and are immaterial to the inventoried change. Revision binding
Diff trigger inventory
Per-item
Overall status check
What stood up
|
Uh oh!
There was an error while loading. Please reload this page.
Item 3a of https://github.com/quantfive/codepress/issues/5858 (Video editor v1).
Stacked on #15 (
ve-3a0-editorhost-subscribe) — this PR's base isve-3a0-editorhost-subscribe; retarget tostagingonce #15 merges.Why
Cut-via-transcript is a stated product goal that could not be expressed at all:
ripple_deleteis a realEditCommandwith a working engine implementation, butcapabilityForCommandreturnednullfor it, socontroller.submitEditrejected the batch as unsupported before it ever reached the host — even though the CodePress host allowlists it.action: 'captions'in its preview request, so captions were the only thing the UI could ever emit.What changed
src/features/editor/host/contract.tsripple_deleteadded toSUPPORTED_HOST_COMMANDS;capabilityForCommand('ripple_delete')now returns'timeline.remove'(alongsideremove_item).EditorTranscriptPort.requestTranscription({ assetId, language? }): HostTranscriptStatusReceipt— signature only, gated by the existingmedia.transcriptioncapability.packages/freecut-editor/src/index.d.ts.src/features/editor/host/transcript-editor.tsxpreviewSelection(action)takes the action, and a new Cut selection affordance reuses the existing preview →submitEditpath verbatim withaction: 'cut'.'cut'is the normalized action the CodePress adapter emits (_ACTION_ALIASESmapsripple_cut→cut, andpreview.actionechoes"cut"); the resulting batch is made ofripple_deletecommands, which the existingcommandIsSupportedguard now passes because of the contract change.Apply cut/Apply captions).status !== 'succeeded'branch gains a Transcribe affordance, shown only when the port implementsrequestTranscriptionandmedia.transcriptionis on. It calls the port, then pollsgetStatus()until the receipt is terminal, and refreshes onsucceeded.getStatus()still takes no arguments (one transcript per project) — unchanged by design.VITE_HOST_TRANSCRIBE_POLL_MS(default3000) andVITE_HOST_TRANSCRIBE_POLL_MAX_ATTEMPTS(default200).Version: the package is bumped to
0.3.4. #16 published 0.3.2 and #15 publishes 0.3.3 on merge, so the OIDC publish workflow's already-published guard means this PR must carry its own version for these surface changes to reach the registry.editor.tsx,vite.editor-package.config.ts, export, and the release workflows are untouched.Tests
controller.test.ts: aripple_deletebatch reacheshost.submitEditand lands revision 1; the same batch is gatedunsupportedwhentimeline.removeis off;SUPPORTED_HOST_COMMANDSassertion updated.transcript-editor.test.tsx: Cut selection emits a preview request withaction: 'cut'and itsripple_deletebatch reachessubmitEdit; Transcribe appears only when the port implementsrequestTranscriptionand the capability is on, and polling reachessucceeded.Canonical QA report posted as a comment.