Skip to content

fix(wizard): pin workflow persist to the source workspace - #134

Merged
IAnMove merged 1 commit into
mainfrom
cursor/critical-bug-management-2d44
Sep 4, 2026
Merged

fix(wizard): pin workflow persist to the source workspace#134
IAnMove merged 1 commit into
mainfrom
cursor/critical-bug-management-2d44

Conversation

@cursor

@cursor cursor Bot commented Sep 4, 2026

Copy link
Copy Markdown

Resumen ejecutivo

Esta primera sección está pensada para project managers y revisores no técnicos. Mantén el detalle técnico completo más abajo.

Qué cambia

Los checkpoints del Wizard ya no pueden guardarse en la carpeta de destino cuando el usuario cambia de workspace a mitad de un guardado en conflicto.

Para qué sirve

Evita que un workflow en curso de la carpeta A se mezcle o sobrescriba los workflows persistidos de la carpeta B.

Impacto para el usuario

Si cambia de carpeta de salida mientras un workflow del Wizard reintenta un guardado, B conserva sus propios checkpoints y A sigue recibiendo el suyo.

Riesgo

  • Bajo
  • Medio
  • Alto

Estado

  • En desarrollo
  • Listo para revisión
  • Bloqueado por CI o revisión
  • Requiere migración o acción manual

Summary

WizardWorkflowRuntime.persist() cloned the in-memory collection correctly, but CAS conflict retries called load(this.workspace) / save(this.workspace) against the live pointer. open() rebinds that pointer immediately, so a folder switch during the retry merged the source checkpoint into the destination .wizard-workflows-v1.json and then replaced the in-memory collection.

This is distinct from the rejected conversation-CAS bug (hocuspocus#48 / PR #122). Conversations already pin writes by workspace; workflow checkpoints did not.

Overview

Concrete trigger:

  1. Workspace A has a waiting Wizard workflow; workspace B already has its own checkpoint.
  2. A task event updates A's workflow and persist() hits a CAS conflict (second tab, concurrent workflow save, or overlapping persist).
  3. While that first save is in flight, the footer output folder changes to B and the panel calls open('workspace-b').
  4. Before this fix, the retry loaded B, mergeCollections'd A's workflows into B, and saved the mix to B. A's latest state was also lost.

The fix pins targetWorkspace / openSequence at the start of persist(). Retries always read/write that workspace. In-memory collection updates are applied only if the runtime still owns that open. persistAndEmit no longer throws Workflow does not exist after a switch.

Detailed changes

Backend

No backend changes.

UI and Wizard

  • ui/src/features/agent/wizardWorkflowRuntime.ts: pin persist target; guard in-memory updates; tolerate emit after switch.
  • ui/tests/wizardWorkflowRuntime.test.mjs: per-workspace mock that conflicts+holds the first save, then asserts B is untouched and A receives the running checkpoint.

The regression test fails on the old pointer (workflow-a appears in B) and passes with the pin.

Data, provenance and compatibility

No schema or file-format change. Existing workflow JSON remains valid.

Files and ownership

  • ui/src/features/agent/wizardWorkflowRuntime.ts — persist/open race fix.
  • ui/tests/wizardWorkflowRuntime.test.mjs — regression coverage.
  • Conversation persistence (wizardConversationPersistence.ts) was left untouched; that path already pins writes.

Validation

  • Focused UI tests: cd ui && npx tsx --tsconfig tsconfig.app.json --import ./tests/setupI18n.ts --test tests/wizardWorkflowRuntime.test.mjs tests/rhythmic3dWorkflow.test.mjs tests/wizardConversationPersistence.test.mjs — 33 passed, 0 failed
  • Confirmed the new test fails on the unfixed persist (destination store gains workflow-a) and passes after the pin
  • git diff --check — clean
  • python scripts/verify_clean_repo.py — N/A (no Python changes)
  • python -m compileall — N/A
  • cd ui && npm run i18n:check — N/A (no copy changes)
  • cd ui && npm run lint -- --max-warnings=0 — not rerun; edited files have no linter errors
  • cd ui && npm run build — N/A (logic-only, covered by unit tests)
  • E2E/smoke checks: N/A (race is unit-tested with a deterministic hold/conflict mock)

Code quality

  • Score: pending CI
  • Complexity trend: pending CI
  • Production LOC trend: pending CI
  • Regression versus main: pending CI
  • Ratchet: pending CI

CI and review

  • CI: pending
  • Cursor/Bugbot: pending
  • Human review: pending

Coste de la tarea

  • Tests simulados: 0 tokens externos
  • Tests reales: N/A
  • Llamadas LLM externas: 0
  • Tokens de prompt: N/A
  • Tokens de respuesta: N/A
  • Tokens totales: N/A
  • Generaciones de imágenes/audio/vídeo: 0
  • Tiempo transcurrido: N/A
  • Proveedores/modelos: N/A

Notes and limitations

  • The first save(this.workspace, snapshot) already captured the workspace argument; the corrupt write happens on the conflict retry after open() rebinds the pointer. The test forces that retry.
  • A late emit of the source workflow after switch is ignored by the panel (isWizardConversationWriteCurrent).
  • Alpha flattening on Tools image upscale (RGBA → RGB) was reviewed and not included: it is the existing wgp.convert_image pipeline, not a cross-workspace data-loss bug.

Follow-up work

None required for this race. Optional later: serialize persist() globally so two workflows cannot CAS-conflict on the same collection.

Checklist

  • The executive summary is understandable without reading the code.
  • The detailed Summary/Overview has not been removed or shortened.
  • Tests and their actual results are recorded.
  • Generated assets, secrets and local-only files are not committed.
  • Required CI and Cursor/Bugbot review are complete, or the PR is clearly marked as waiting for them.
Open in Web View Automation 

An in-flight checkpoint that hit a CAS conflict retried against the live
workspace pointer. Switching folders during that retry merged the source
workflows into the destination store.

Co-authored-by: ignaciodelcano+dcl <ignaciodelcano+dcl@gmail.com>
@github-actions

github-actions Bot commented Sep 4, 2026

Copy link
Copy Markdown

PR Review — Loreframe Studio

Risk: low
Scope: 2 file(s); +115/-5; React UI

Automated review from scripts/analyze_pr.py. This is a heuristic pass (no LLM) so humans still own the merge decision.

Findings

  • low — UI changed — rebuild before merge
    Run cd ui && npm run build (CI already does this). Pinokio Update rebuilds for end users; keep ui/dist untracked.

Changed files

  • modified: ui/src/features/agent/wizardWorkflowRuntime.ts, ui/tests/wizardWorkflowRuntime.test.mjs

CONTRIBUTING checklist

  • python scripts/verify_clean_repo.py
  • python -m compileall -q app/services app/launch.py scripts
  • cd ui && npm run build if the UI changed
  • No weights, CivitAI sidecars, or generated guides
  • Stays local-first (no required accounts / telemetry)

Posted by the repo PR review workflow. Re-runs on each push to the PR.

@github-actions

github-actions Bot commented Sep 4, 2026

Copy link
Copy Markdown

Code health

Quality score: 49.2/100

Higher is better. The score is a trend dashboard; the independent ratchet below remains the CI gate.

Component Weight Current Change
Cyclomatic health 45% 52.2 +0.0
File concentration 25% 54.1 +0.0
Oversized-file debt 20% 29.5 +0.0
Modularity 10% 62.5 +0.0

Change vs PR base: +0.0 points.

Metric Value
Production LOC 241,328
Production files 532
Test LOC 70,178
Functions measured 15,085
Functions complexity ≥ 15 784
Maximum complexity 667

Markdown, JSON catalogs and tests are out of this table. Only app/ runtime + ui/src TS/JS count.

Most complex functions

Complexity Where
667 app/wgp.py:7164 generate_video
374 ui/src/stores/useStore.ts:4021 Async method 'startGeneration'
355 app/_launch_runtime.py:23472 _run_generation
308 app/wgp.py:12281 generate_video_tab
271 ui/src/components/Sidebar/SceneAnimatorPanel.tsx:474 Function 'SceneAnimatorPanel'
266 ui/src/stores/useStore.ts:8563 Async method 'loadSettingsFromOutput'
258 app/services/director/planners/short_film.py:3433 ShortFilmPlanner._plan_story_driven
248 app/services/director_pipeline.py:13735 _run_video_generation
245 app/services/director_pipeline.py:7860 _run_pipeline
243 ui/src/features/agent/agentActions.ts:1109 Function 'parseAction'
226 app/services/director_pipeline.py:6689 update_comic_preview
225 ui/src/features/agent/agentActions.ts:2766 Async function 'executeAgentActions'

Trend vs baseline

Metric Δ
Production LOC +16
Test LOC +94
Functions ≥ 15 +0
Maximum complexity +0

Warnings

  • production LOC increased by +16

Ratchet passed.

@IAnMove

IAnMove commented Sep 4, 2026

Copy link
Copy Markdown
Owner

cursor review

@cursor

cursor Bot commented Sep 4, 2026

Copy link
Copy Markdown
Author

Bugbot couldn't run — GitHub account mismatch

The GitHub account linked to your Cursor account does not match the PR author.

Please ensure you're using the correct GitHub account, or run Bugbot from a team that covers this repository.

@IAnMove
IAnMove marked this pull request as ready for review September 4, 2026 15:52
@IAnMove
IAnMove merged commit 247554a into main Sep 4, 2026
5 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.

2 participants