test: separar validación local de smoke real - #131
Conversation
PR Review — Loreframe StudioRisk: medium Automated review from Findings
Changed files
CONTRIBUTING checklist
Posted by the repo PR review workflow. Re-runs on each push to the PR. |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using high effort and found 3 potential issues.
Bugbot Autofix prepared fixes for both issues found in the latest run.
- ✅ Fixed: Revoice upload source resolution fails
- runTool now forwards toolsSourceWorkspace (including uploads) on submitToolRevoice so confined resolve_source can find uploaded clips.
- ✅ Fixed: Simulated tool sidecar omits tags
- Simulated upscale/revoice sidecars now write edit_sub_mode and the concrete tool name, matching _write_tool_sidecar and the asset manifest origin.
Or push these changes by commenting:
@cursor push 72060fd160
Preview (72060fd160)
diff --git a/app/_launch_runtime.py b/app/_launch_runtime.py
--- a/app/_launch_runtime.py
+++ b/app/_launch_runtime.py
@@ -23719,22 +23719,25 @@
return False
output_name = os.path.basename(generated_path)
record_job_outputs(job, [output_name])
- tool_job = str(params.get("_non_durable_tool") or "") in {"upscale", "revoice"}
+ tool_name = str(params.get("_non_durable_tool") or "")
+ tool_job = tool_name in {"upscale", "revoice"}
sidecar_params = params
if tool_job:
# Simulation still exercises the real queue/task/manifest path, but
# host filesystem paths and uploaded voice references must never enter
- # the durable sidecar.
+ # the durable sidecar. Mirror _write_tool_sidecar so gallery filters
+ # and manifests see the concrete tool name plus edit_sub_mode.
sidecar_params = {
key: value
for key, value in params.items()
if not str(key).startswith("_")
and key not in {"source_path", "video_path", "voice_ref_paths"}
}
+ sidecar_params["edit_sub_mode"] = tool_name
sidecar = {
"params": sidecar_params,
"generation_mode": params.get("generation_mode"),
- "tool": "tools" if tool_job else None,
+ "tool": tool_name if tool_job else None,
"capability": params.get("capability") if tool_job else None,
"job_id": job.get("id"),
"task_id": job.get("task_id"),
@@ -23749,7 +23752,12 @@
sidecar["inputs"] = params.get("inputs") or []
sidecar["parents"] = params.get("parents") or []
sidecar["transformations"] = params.get("transformations") or []
- _publish_generation_sidecar_for_studio_job(job, generated_path, sidecar)
+ _publish_generation_sidecar_for_studio_job(
+ job,
+ generated_path,
+ sidecar,
+ tool=tool_name if tool_job else "studio",
+ )
if not finalize:
return update_job(
job,
diff --git a/ui/src/api/generation.ts b/ui/src/api/generation.ts
--- a/ui/src/api/generation.ts
+++ b/ui/src/api/generation.ts
@@ -292,6 +292,7 @@
diffusion_steps?: number
cfg_rate?: number
workspace?: string
+ source_workspace?: string
}): Promise<{ job_id: string }> {
const res = await fetch(`${BASE}/api/v1/tools/revoice`, {
method: 'POST',
diff --git a/ui/src/stores/useStore.ts b/ui/src/stores/useStore.ts
--- a/ui/src/stores/useStore.ts
+++ b/ui/src/stores/useStore.ts
@@ -3925,7 +3925,13 @@
provenance: { actor: 'user' },
})
: tool === 'revoice'
- ? await api.submitToolRevoice({ video_path: source, voice_ref_paths: refPaths, mode: s.toolsRevoiceMode, workspace: s.activeWorkspace })
+ ? await api.submitToolRevoice({
+ video_path: source,
+ voice_ref_paths: refPaths,
+ mode: s.toolsRevoiceMode,
+ workspace: s.activeWorkspace,
+ source_workspace: s.toolsSourceWorkspace || undefined,
+ })
: await api.submitToolRemoveBackground({
asset_id: s.toolsSourceAssetId || undefined,
source,You can send follow-ups to the cloud agent here.
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit 761ff95. Configure here.
| method: s.toolsUpscaleMethod, | ||
| workspace: s.activeWorkspace, | ||
| provenance: { actor: 'user' }, | ||
| }) |
There was a problem hiding this comment.
Revoice upload source resolution fails
High Severity
runTool still submits revoice with only video_path and the active workspace, while tools_revoice now resolves through confined _resolve_tool_source. Uploaded clips are tagged __uploads__ in the panel but that scope never reaches the API, so a bare upload filename is looked up in the destination workspace and the request fails.
Additional Locations (2)
Reviewed by Cursor Bugbot for commit 761ff95. Configure here.
| "params": sidecar_params, | ||
| "generation_mode": params.get("generation_mode"), | ||
| "tool": "tools" if tool_job else None, | ||
| "capability": params.get("capability") if tool_job else None, |
There was a problem hiding this comment.
Simulated tool sidecar omits tags
Medium Severity
Simulated upscale and revoice sidecars set tool to tools and never write edit_sub_mode, while the real worker publishes tool as upscale/revoice plus that gallery tag. Simulated tool outputs therefore classify differently from real runs.
Reviewed by Cursor Bugbot for commit 761ff95. Configure here.
| method: s.toolsUpscaleMethod, | ||
| workspace: s.activeWorkspace, | ||
| provenance: { actor: 'user' }, | ||
| }) |
There was a problem hiding this comment.
Upscale result skips asset refresh
Low Severity
toolsAssetsRevision increments only after remove-background completes. A finished image upscale never refreshes the Tools library grid, so the derived PNG stays invisible as a source until the panel remounts.
Reviewed by Cursor Bugbot for commit 761ff95. Configure here.
Code healthQuality score: 49.0/100Higher is better. The score is a trend dashboard; the independent ratchet below remains the CI gate.
Change vs PR base: -0.3 points.
Markdown, JSON catalogs and tests are out of this table. Only Most complex functions
Trend vs baseline
Warnings
Ratchet passed. |



Añade rutina local provider-free para pre-push y wrapper explícito para smoke real ACE/H3. Los E2E normales siguen simulados; la generación real requiere confirmación y nunca se ejecuta en CI. Incluye documentación y no toca launchers.
Note
Medium Risk
Large changes in
_launch_runtime.pyjob routing and filesystem source resolution affect GPU tools and gallery metadata; boundaries are shared with existing rembg tooling but revoice voice-ref resolution and cancellation cleanup add regression surface.Overview
Tools upscale now handles still images and videos through one API and worker. Requests resolve sources via the same confined asset/path rules as background removal (
_resolve_tool_source+ extendedresolve_source), publish richer sidecars (lineage, capability, provenance), and route images through_upscale_tool_imagewithperform_spatial_upsampling(..., still_image=True)while videos keep the audio-preserving pipeline. Revoice reuses that resolver for video-only sources; cancel/ interrupt paths drop late upscale artifacts.The Studio Tools UI switches image selection to a thumbnail grid (also used for upscale media), submits
source/source_kindwith provenance, and adds Playwright/unit coverage for upscale alongside remove-background updates.Developer workflow:
scripts/validate_local.shruns contract pytest, UI test/lint/build, and simulated E2E without GPU or providers;run_real_media_smoke.shgates real ACE smoke behind explicit env confirmation and is documented inLOCAL_VALIDATION.md.CI / ratchet: PR code-health checks compare against the base commit report (
--baselinefrom a worktree), hotspot per-PR allowance rises to 600 lines, andAPI.mddocuments the upscale contract.Reviewed by Cursor Bugbot for commit 761ff95. Configure here.