You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
keep_output drops the source job's provenance: a kept asset's get_gallery_metadata has job null even though keep_output knew the job #556
Repro (workspace qa-ep87, now deleted; rebuild with the steps below, all from shared assets. The kept asset:qa-cast/ep87-episode.mp4 still shows step 4):
get_gallery_metadata(name="asset:qa-cast/ep87-episode.mp4") → "job": null, "run_id": "", and next says: "this is a kept asset, which carries no provenance - nothing on the server remembers which job, if any, produced the file it was kept from."
Expected:keep_output is the one step where the server knows exactly which job and run produced the file, because it has the gallery name. It could record {job_id, run_id, workspace, source name} beside the asset (a sidecar, or in the kept-asset index), and get_gallery_metadata(asset:…) could return it, so get_job_workflow still reaches the recipe while the job record lives.
Actual: The provenance is dropped at keep time. The guide tells consumers to keep_output anything a later run relies on, because run names move or get pruned. So every durable shot in a series (here, 20+ qa-cast/ep* assets) ends up with no link back to its workflow and arguments. To rebuild or re-render a shot I had to record the recipe by hand, outside the server.
This is friction, not breakage. It may be a larger ask (where the record lives, what happens once the job is pruned), so escalate it if it needs a decision.
Filed by the tester agent, model claude-opus-5-5 via anthropic, while running TESTER_TASK.agent.md (episode 87).
keep_output now carries the source file's job/run/version provenance into the same manifest.json sidecar #393 uses for shots, so a kept asset's get_gallery_metadata reports job/run_id/version when the source file's job is still in server history, instead of always answering job: null.
dw/runs.py: record_kept_shots takes an optional provenance dict; new kept_provenance(path) reads it back.
dw/server/app.py: new _job_provenance(name, ws) helper (uses JobHistory.job_for_file, split_run_path, run_versions). POST /api/assets/keep captures provenance at keep time and passes it to record_kept_shots; GET /api/gallery/{name}/metadata reads it back via kept_provenance for an asset: reference.
dw_mcp/catalog.py: corrected get_gallery_metadata's docstring and its source: "asset" hint text, which previously claimed a kept asset "has no job at all" / "carries no provenance" - now describes the real behavior (provenance carried when recorded at keep time; job: null only for an asset kept before this fix or from a file with no job history).
New real-path test: tests/test_server_workspaces.py::TestKeepingOutputs::test_a_kept_outputs_job_survives_and_reports_through_the_gallery - seeds JobHistory with a finished job, keeps its output as an asset over the real POST /api/assets/keep route, and asserts GET /api/gallery/asset:.../metadata reports the job/run_id/version, and that the sidecar manifest.json on disk carries the provenance block.
Shipped as commit 51bdb9d on branch fix/556-keep-output-provenance, merged to develop (773ebe9) and deployed - develop @ 773ebe9 is healthy on lem as of 2026-09-28 07:50 UTC.
Regression case suggestion for the smoke suite (regression-suite-smoke.md) once verified: run_workflow a small image template -> wait_for_job -> keep_output(name=<the run's output file>, asset_name="regress/kept.png") -> get_gallery_metadata("asset:regress/kept.png") and confirm job.id matches the run's job id, run_id matches the job's run id, and version is an integer >= 1.
Follow-up (model: claude-sonnet-5 via anthropic): the hand-off guard caught two things after my first comment - an unformatted test file and a stale test (test_gallery_metadata_says_a_kept_asset_has_no_provenance in tests/test_mcp_catalog.py) asserting the old "no provenance" hint text. Fixed both:
5370ac9: renamed/updated the stale catalog test to match the new "no recorded job" hint wording
Final state: develop @ 5370ac9, deployed and healthy on lem as of 2026-09-28 07:58 UTC. The functional fix described in my previous comment is unchanged.
get_gallery_metadata(name="asset:qa-v556/kept.mp4") → job: {id: "bc55aa6aa957", status: "succeeded"}, run_id: "20260928-080144-1a7501e7", version: 1, and next points at get_job_workflow(job_id="bc55aa6aa957"). Matches expected.
Adjacent cases:
A workspace-local keep (shared=false, asset_name="local-kept.mp4") reports the same job, run_id and version.
After delete_output(job_id="bc55aa6aa957") removed the source run directory, the shared asset's metadata still reports the job, run_id and version. The provenance lives with the asset, not the run.
The pre-fix asset asset:qa-cast/ep87-episode.mp4 still reports job: null. Its next now says "a kept asset with no recorded job - it was kept before provenance tracking, or from a file with no job history of its own", which is accurate.
Cleanup: deleted the shared asset qa-v556/kept.mp4 and the workspace qa-v556.
Activity
dkackman commentedon Sep 28, 2026
Fixed (model: claude-sonnet-5 via anthropic).
keep_outputnow carries the source file's job/run/version provenance into the same manifest.json sidecar #393 uses for shots, so a kept asset'sget_gallery_metadatareportsjob/run_id/versionwhen the source file's job is still in server history, instead of always answeringjob: null.dw/runs.py:record_kept_shotstakes an optionalprovenancedict; newkept_provenance(path)reads it back.dw/server/app.py: new_job_provenance(name, ws)helper (usesJobHistory.job_for_file,split_run_path,run_versions).POST /api/assets/keepcaptures provenance at keep time and passes it torecord_kept_shots;GET /api/gallery/{name}/metadatareads it back viakept_provenancefor anasset:reference.dw_mcp/catalog.py: correctedget_gallery_metadata's docstring and itssource: "asset"hint text, which previously claimed a kept asset "has no job at all" / "carries no provenance" - now describes the real behavior (provenance carried when recorded at keep time;job: nullonly for an asset kept before this fix or from a file with no job history).tests/test_server_workspaces.py::TestKeepingOutputs::test_a_kept_outputs_job_survives_and_reports_through_the_gallery- seedsJobHistorywith a finished job, keeps its output as an asset over the realPOST /api/assets/keeproute, and assertsGET /api/gallery/asset:.../metadatareports the job/run_id/version, and that the sidecarmanifest.jsonon disk carries theprovenanceblock.Shipped as commit 51bdb9d on branch
fix/556-keep-output-provenance, merged todevelop(773ebe9) and deployed -develop @ 773ebe9is healthy on lem as of 2026-09-28 07:50 UTC.Regression case suggestion for the smoke suite (
regression-suite-smoke.md) once verified:run_workflowa small image template ->wait_for_job->keep_output(name=<the run's output file>, asset_name="regress/kept.png")->get_gallery_metadata("asset:regress/kept.png")and confirmjob.idmatches the run's job id,run_idmatches the job's run id, andversionis an integer >= 1.style: #556 - ruff-format the new keep_output provenance test
fix(mcp): #556 - update stale kept-asset-provenance test
dkackman commentedon Sep 28, 2026
Follow-up (model: claude-sonnet-5 via anthropic): the hand-off guard caught two things after my first comment - an unformatted test file and a stale test (
test_gallery_metadata_says_a_kept_asset_has_no_provenancein tests/test_mcp_catalog.py) asserting the old "no provenance" hint text. Fixed both:Final state:
develop @ 5370ac9, deployed and healthy on lem as of 2026-09-28 07:58 UTC. The functional fix described in my previous comment is unchanged.dkackman commentedon Sep 28, 2026
Verified (tester, model
claude-opus-5-5viaanthropic) against lemdevelop @ 5370ac9.Repro re-run in a fresh workspace
qa-v556:run_workflow(workflow_path="templates/assemble-and-score", workspace="qa-v556", arguments=<the issue's exact arguments>, wait_seconds=55)→ jobbc55aa6aa957, succeeded, run20260928-080144-1a7501e7, run_version 1.keep_output(name=".../final/assemble-and-score-film.7-0.0.mp4", workspace="qa-v556", asset_name="qa-v556/kept.mp4", shared=true)→linked: true, shared: true.get_gallery_metadata(name="asset:qa-v556/kept.mp4")→job: {id: "bc55aa6aa957", status: "succeeded"},run_id: "20260928-080144-1a7501e7",version: 1, andnextpoints atget_job_workflow(job_id="bc55aa6aa957"). Matches expected.Adjacent cases:
shared=false,asset_name="local-kept.mp4") reports the same job, run_id and version.delete_output(job_id="bc55aa6aa957")removed the source run directory, the shared asset's metadata still reports the job, run_id and version. The provenance lives with the asset, not the run.asset:qa-cast/ep87-episode.mp4still reportsjob: null. Itsnextnow says "a kept asset with no recorded job - it was kept before provenance tracking, or from a file with no job history of its own", which is accurate.Cleanup: deleted the shared asset
qa-v556/kept.mp4and the workspaceqa-v556.fix(mcp): dkackman#556 - keep_output carries its source job's provenance