Skip to content

feat(provenance): trace Studio generations from Wizard to asset - #95

Merged
IAnMove merged 4 commits into
mainfrom
feat/provenance-studio-wizard
Sep 2, 2026
Merged

feat(provenance): trace Studio generations from Wizard to asset#95
IAnMove merged 4 commits into
mainfrom
feat/provenance-studio-wizard

Conversation

@IAnMove

@IAnMove IAnMove commented Sep 2, 2026

Copy link
Copy Markdown
Owner

Summary

  • creates the Wizard command identity before execution and carries actor/capability/correlation context through Studio
  • preserves the canonical task ID separately from the backend polling job ID
  • persists provenance across ordinary generation queue recovery and publishes it to Activity and canonical asset manifests
  • distinguishes logical Workspace collections from physical output folders and validates supplied collection IDs
  • covers ordinary Studio image/video/audio, SFX, and local/remote/simulated 3D generation; Studio edit-tool provenance remains a separate follow-up
  • uses best-effort manifest publication so metadata failure cannot destroy a completed generation

Verification

  • 500/500 UI tests
  • 100 focused Python tests after rebase onto current main
  • ESLint and TypeScript build pass
  • focused E2E now cross-checks one Wizard command ID against its canonical task and final asset manifest
  • clean-repo guard and git diff check pass

Identity contract

The backend job ID remains the polling/cancellation handle. task_id is the canonical Activity identity and is now required before the Wizard reports a generation as queued. A physical output folder is never invented as a logical workspace_id.


Note

Medium Risk
Touches core generation enqueue, persistence, and public metadata APIs; provenance is attribution-only but incorrect wiring could break clients or mis-attribute outputs.

Overview
Adds an end-to-end generation provenance path so Wizard commands and manual Studio submits can be correlated with Activity tasks and output asset manifests.

Backend: Clients may send optional provenance on /api/v1/generate and /api/v1/model3d/generate; it is normalized via normalize_submission_provenance (actor/capability/command correlation only—no spoofed job/task IDs or output folders). Unknown workspace_id collection IDs are rejected. Jobs store provenance, persist it through queue recovery, and assign canonical task_id / root_task_id at creation (still used if Activity publication fails). Activity task metadata and asset sidecars now carry actor, tool, capability, and command IDs; Studio and 3D outputs publish through shared helpers using publish_generation_sidecar_best_effort so manifest failures cannot break completed generations. Manifest timing includes queued_at.

Frontend: GenerationSubmissionContext flows from the Generate button (user) and Wizard capabilities (wizard + commandId) into generation requests; jobs track taskId / rootTaskId separately from the polling job_id, and Wizard queuing reports the canonical task id (including Hunyuan3D).

Tests and live E2E assert command → task → output metadata alignment.

Reviewed by Cursor Bugbot for commit 8eff12a. Configure here.

@github-actions

github-actions Bot commented Sep 2, 2026

Copy link
Copy Markdown

PR Review — Loreframe Studio

Risk: low
Scope: 23 file(s); +522/-83; React UI, backend services

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

  • added: tests/test_generation_provenance_submission.py, ui/src/features/studio/generationProvenance.ts
  • modified: app/_launch_runtime.py, app/services/asset_manifest.py, app/services/generation_provenance.py, app/services/model3d_service.py, tests/test_execution_mode.py, tests/test_h3_preplan_job_contract.py, tests/test_provenance_3d_director.py, ui/e2e/live-specs/wizard-generation.spec.ts, ui/src/api/model3d.ts, ui/src/components/Sidebar/GenerateButton.tsx, ui/src/features/agent/agentActions.ts, ui/src/features/agent/applicationAdapters.ts, ui/src/features/agent/capabilityRegistry.ts, ui/src/features/agent/capabilityRunner.ts, ui/src/features/agent/studioCapabilities.ts, ui/src/features/studio/actions.ts, ui/src/features/studio/adapters.ts, ui/src/stores/useStore.ts, ui/src/types/index.ts, ui/tests/agentActions.test.mjs
    … and 1 more

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.

@IAnMove

IAnMove commented Sep 2, 2026

Copy link
Copy Markdown
Owner Author

cursor review

@cursor cursor 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.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Autofix Details

Bugbot Autofix prepared a fix for the issue found in the latest run.

  • ✅ Fixed: Queued jobs can lack task IDs
    • _new_generation_job now assigns the deterministic task-generation-{job_id} identity before Activity publish, so /api/v1/generate still returns a task_id if publication fails and the Wizard will not retry a second job.

Create PR

Or push these changes by commenting:

@cursor push 03c31efe38
Preview (03c31efe38)
diff --git a/app/_launch_runtime.py b/app/_launch_runtime.py
--- a/app/_launch_runtime.py
+++ b/app/_launch_runtime.py
@@ -632,6 +632,8 @@
         "provenance": copy.deepcopy(provenance or {}),
         "recovered": recovered,
     }
+    job.setdefault("task_id", f"task-generation-{job['id']}")
+    job.setdefault("root_task_id", job["task_id"])
     # Reserve FIFO order synchronously. Starting one thread per request is
     # still useful for cancellation/recovery, but thread scheduling no longer
     # decides which submitted generation reaches the GPU first.
@@ -642,8 +644,10 @@
         try:
             task = publisher(job)
             if isinstance(task, dict):
-                job["task_id"] = task.get("id")
-                job["root_task_id"] = task.get("root_id")
+                job["task_id"] = task.get("id") or job["task_id"]
+                job["root_task_id"] = (
+                    task.get("root_id") or task.get("id") or job["root_task_id"]
+                )
         except Exception as exc:
             print(f"[Task registry] Could not publish generation {job['id']}: {exc}")
     return job

You can send follow-ups to the cloud agent here.

Comment thread app/_launch_runtime.py
IAnMove added a commit that referenced this pull request Sep 2, 2026
Extract Music, Trailer, Productions and Compact workspace into
composable panels so the files that CI treated as new 100-complexity
hotspots are no longer single functions. Refresh the code-health
baseline after that split.

CI now prints a GitHub table in the job summary and upserts the same
table as a PR comment. Markdown, JSON catalogs and tests stay out of
the product complexity scan. The token heuristic no longer matches
`task-generation-...` ids (false positive on #95).
@IAnMove

IAnMove commented Sep 2, 2026

Copy link
Copy Markdown
Owner Author

@cursor review

@cursor cursor 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.

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit 8eff12a. Configure here.

@IAnMove
IAnMove merged commit f4db971 into main Sep 2, 2026
5 checks passed
@IAnMove
IAnMove deleted the feat/provenance-studio-wizard branch September 5, 2026 11:53
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