Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
264 commits
Select commit Hold shift + click to select a range
f617c19
fix(memory): #348 - fit host memory projection as fixed+marginal, not…
dkackman Sep 22, 2026
e9e44d5
docs: 2026-09-22 quality review and remediation plan
dkackman Sep 22, 2026
5ca3d40
fix(introspection): #350 - describe real image-processor parameters, …
dkackman Sep 23, 2026
1fd7c04
fix(video): #367 - get_frame seeks one frame instead of decoding the …
dkackman Sep 23, 2026
dc47a3d
fix(introspection): #366 - give get_first_frame/get_last_frame their …
dkackman Sep 23, 2026
b9abb7e
Merge branch 'fix/processor-task-introspection-350-366-367' into develop
dkackman Sep 23, 2026
8a41883
fix(mcp): #353 - configured absolute URLs, auth-aware export handoff,…
dkackman Sep 23, 2026
3438999
Merge branch 'fix/export-public-url-353' into develop
dkackman Sep 23, 2026
3dc697a
fix(plugin): #355 - skills tell agent to use clear_memory instead of …
dkackman Sep 23, 2026
abc9b61
fix(server): #356 - accept output: prefix on gallery reads, add media…
dkackman Sep 23, 2026
b7b5227
fix(events): #357 - reword phase_stall watchdog as informational, not…
dkackman Sep 23, 2026
9e07b5c
fix(mcp): #359 - clearer messages for three misdiagnosed errors
dkackman Sep 23, 2026
86d37c8
fix(mcp): #360 - run_workflow's queued answer names its workspace
dkackman Sep 23, 2026
dbe6d26
fix(templates): #362 - minimax/music balanced step normalizes to -3 dBFS
dkackman Sep 23, 2026
277265e
fix(introspection): #364 - null-defaulted variable feeding a required…
dkackman Sep 23, 2026
e5bfb9e
fix(engine): #365 - media name-conventions no longer pre-load the var…
dkackman Sep 23, 2026
fed4ec5
fix(deploy): update SSH command syntax for clarity
dkackman Sep 23, 2026
d10c858
fix(mcp): fit server instructions and tool descriptions under the cli…
dkackman Sep 23, 2026
c1e103b
format
dkackman Sep 23, 2026
a737bbd
docs(proposals): retire the two shipped proposals
dkackman Sep 23, 2026
a918105
test: fix tests that checked nothing, drop ones that gated nothing
dkackman Sep 23, 2026
4493fa8
fix(ui): enhance directory hint styling for better responsiveness
dkackman Sep 23, 2026
56bdb9b
test: second pass - drop duplicate MCP/server tests, fix weak ones
dkackman Sep 23, 2026
ea8a0b6
fix(engine): resolve previous_result: references inside a task's inpu…
dkackman Sep 23, 2026
96e2ea2
fix(plugin): #340, #354 - score ducking recipe + transcription route …
dkackman Sep 23, 2026
ea460a8
fix(engine): #341 - bucket a composed child's observed cost by the co…
dkackman Sep 23, 2026
fc8c1ea
fix(engine): #343 - heartbeat DownloadWatch on a timer to close the x…
dkackman Sep 23, 2026
998a739
fix(engine): #349 - add a CPU grade task for images and video
dkackman Sep 23, 2026
4e6cef7
Merge branch 'fix-349-grade-task' into develop
dkackman Sep 23, 2026
9368b20
fix(engine): #349 - ruff format test_grade.py
dkackman Sep 23, 2026
2f1c6c8
fix(catalog): #351 - every generative entry declares seed: variable:seed
dkackman Sep 23, 2026
0945e65
fix(catalog): #352 - add shots-batch template for unrelated H3 shots
dkackman Sep 23, 2026
05abba5
Merge branch 'fix-351-352-seed-convention' into develop
dkackman Sep 23, 2026
c128018
fix(mcp): #353 - sync served tool descriptions with the auth-aware ex…
dkackman Sep 23, 2026
ce1da94
Merge branch 'fix-353-mcp-descriptions' into develop
dkackman Sep 23, 2026
1272e71
fix(mcp): #356 - expose list_gallery(media=true) over MCP
dkackman Sep 23, 2026
1f6a97d
Merge branch 'fix-356-list-gallery-media' into develop
dkackman Sep 23, 2026
0da2d97
fix(result): #358 - say 'quiet but not empty' when a near-silent shot…
dkackman Sep 23, 2026
f4da3be
Merge branch 'fix-358-quiet-not-empty' into develop
dkackman Sep 23, 2026
2cae9d0
fix(mcp): #361 - report BS.1770 LUFS/true-peak, add target_lufs to no…
dkackman Sep 23, 2026
bf7c305
Merge branch 'fix-361-lufs-metering' into develop
dkackman Sep 23, 2026
b6db9a4
style(mcp): #361 - ruff format LUFS/target_lufs changes
dkackman Sep 23, 2026
fbb3f58
fix(mcp): #363 - let result.fps take a variable:/item: reference
dkackman Sep 23, 2026
8b357ad
fix(server): #364 - validate_workflow with no arguments matches save_…
dkackman Sep 23, 2026
ec288ed
Merge branch 'fix-364-validate-no-arguments' into develop
dkackman Sep 23, 2026
d5f8d5d
fix(engine): #368 - bound step_cache's retained media by size, not ju…
dkackman Sep 23, 2026
1dd8fed
Merge branch 'fix-368-step-cache-byte-budget' into develop
dkackman Sep 23, 2026
25e145c
fix(engine): #370 - correct out-of-range at/frame: message and error
dkackman Sep 23, 2026
4aaeef7
fix(mcp): #372 - get_gallery_metadata audio hint matches -3 clip fix
dkackman Sep 23, 2026
7f5b63c
fix(engine): #343 - flat downloads stall, bytes never shrink, decimal…
dkackman Sep 23, 2026
4184e78
Merge branch 'fix-343-download-progress-hook' into develop
dkackman Sep 23, 2026
5ccd1fc
fix(engine): #349 - grade accepts video input, enforces temperature/t…
dkackman Sep 23, 2026
336c5d1
Merge branch 'fix-349-grade-video-and-range-rework' into develop
dkackman Sep 23, 2026
4a09cad
fix(mcp): #354 - complete the transcription recipe with validate + ac…
dkackman Sep 23, 2026
95391f2
fix(worker): #368 - release host caches at every job end, not just cl…
dkackman Sep 23, 2026
0963746
Merge branch 'fix-368-host-cache-release-at-job-end' into develop
dkackman Sep 23, 2026
afd6953
fix(workflow): #368 - return host caches at pipeline release, not onl…
dkackman Sep 23, 2026
c4dd377
Merge branch 'fix-368-host-cache-release-on-pipeline-release' into de…
dkackman Sep 23, 2026
ce61b7b
fix(plan): #382 - downloads_required checks completeness, not just pr…
dkackman Sep 23, 2026
13f8cde
Merge branch 'fix-382-download-required-incomplete-repo' into develop
dkackman Sep 23, 2026
8030263
fix(plan): #382 - apply ruff format to new tests
dkackman Sep 23, 2026
11c4369
fix(tasks): #383 - grade's get_task docs describe the command, not th…
dkackman Sep 23, 2026
8e90e32
Merge branch 'fix-383-grade-task-docs' into develop
dkackman Sep 23, 2026
416c6ba
fix(mcp,plugin): correct stale and contradictory agent-facing text
dkackman Sep 23, 2026
4331715
docs(proposals): #375 - decline workspace-folders, move to declined/ …
dkackman Sep 23, 2026
05bc836
Merge branch 'docs/375-decline-workspace-folders' into develop
dkackman Sep 23, 2026
c0e3e4e
docs(readme): ask driving sessions to file feedback with the field-re…
dkackman Sep 24, 2026
ceb2d4d
Merge branch 'docs/field-report-label' into develop
dkackman Sep 24, 2026
525e470
fix(mcp): #384 - get_gallery_metadata points at the actual recovery r…
dkackman Sep 24, 2026
31af829
Merge branch 'fix-384-gallery-metadata-next-hint' into develop
dkackman Sep 24, 2026
b2b8b54
style(mcp): #384 - ruff format test_mcp_catalog.py
dkackman Sep 24, 2026
897dc16
fix(mcp): #389 - scope /api/server directories to the requested works…
dkackman Sep 24, 2026
773e9d6
Merge branch 'fix-389-download-output-workspace-scoping' into develop
dkackman Sep 24, 2026
97ef14b
feat(engine): #385 - record shot boundaries on joined videos and in t…
dkackman Sep 24, 2026
7556673
docs: #385 - document recorded shot boundaries
dkackman Sep 24, 2026
2473820
test(engine): #385 - pin shot boundaries: constructors, joins, overru…
dkackman Sep 24, 2026
c3ee829
Merge branch 'develop' of https://github.com/dkackman/diffusers-workf…
dkackman Sep 24, 2026
2c802c2
test(engine): #385 - shots through Workflow.run's manifest, and the s…
dkackman Sep 24, 2026
e9b40bd
Merge branch 'feat/378-a-shot-boundaries' into develop (#385)
dkackman Sep 24, 2026
8c49c69
fix(engine): #390 - name a joined shot by its file, not its resolved …
dkackman Sep 24, 2026
e554426
Merge branch 'fix/390-shot-name-absolute-path' into develop (#390)
dkackman Sep 24, 2026
9c78993
style(engine): #390 - ruff format
dkackman Sep 24, 2026
1c5ff80
test(security): token, Origin/Host and ungated static routes
claude Sep 24, 2026
851c051
test(security): trust gate refuses before any import, and trust lets …
claude Sep 24, 2026
5b65186
test(security): planted symlinks and download_output destinations
claude Sep 24, 2026
066d206
test(security): decoder bombs through get_output_image and gallery ro…
claude Sep 24, 2026
7ee72d2
test(security): SSRF address spellings, redirects and HF token scope
claude Sep 24, 2026
b5aa656
test(security): documented input caps refused before any work
claude Sep 24, 2026
9969359
Merge remote-tracking branch 'origin/develop' into test/security-gaps
claude Sep 24, 2026
b4a08b3
feat(engine): #387 - assessment probes, rules table, json returns kind
dkackman Sep 24, 2026
f34d7e6
feat(engine): #387 - probe tests, rules table pinned to probe fields,…
dkackman Sep 24, 2026
154a944
Merge branch 'feat/378-b-probes' into develop (#387)
dkackman Sep 24, 2026
d9d1143
fix(engine): #392 - normalize_audio/grade/loop_audio emit structured …
dkackman Sep 24, 2026
1f6d8ab
Merge branch 'fix/392-audio-grade-observability' into develop (#392)
dkackman Sep 24, 2026
9589cae
feat(engine): #387 - seam_level_step compares shot levels, not the se…
dkackman Sep 24, 2026
732cd21
Merge branch 'fix/387-seam-level-step' into develop (#387)
dkackman Sep 24, 2026
eda82ba
feat(engine): #387 - probes read an asset:/output: video from the fil…
dkackman Sep 24, 2026
591705c
Merge branch 'fix/387-probe-stored-media' into develop (#387)
dkackman Sep 24, 2026
fdaa348
fix(engine): #393 - keep_output carries a run's shot records into the…
dkackman Sep 24, 2026
8ac5bb1
Merge branch 'fix/393-keep-output-shots' into develop (#393)
dkackman Sep 24, 2026
4740f2e
style(tests): #393 - ruff format the keep_output shots test
dkackman Sep 24, 2026
8c86cba
fix(engine): #394 - analyze_seams/analyze_shots report rules_skipped,…
dkackman Sep 24, 2026
612d91f
fix(engine): #395 - gain_audio with no region gains the whole track
dkackman Sep 24, 2026
11f19ac
Merge branch 'fix/395-gain-audio-whole-track' into develop (#395)
dkackman Sep 24, 2026
6b0e943
fix(engine): #396 - name a joined shot after its previous_result step
dkackman Sep 24, 2026
3e19762
Merge branch 'fix/396-shot-names-from-previous-result' into develop (…
dkackman Sep 24, 2026
c30b1d2
fix(engine): #396 - reach the live artifact when naming a joined shot
dkackman Sep 24, 2026
6ac2861
Merge branch 'fix/396-shot-names-reach-artifact' into develop (#396)
dkackman Sep 24, 2026
df796cf
fix(mcp): #397 - suggest catalog names for an unresolved workflow
dkackman Sep 24, 2026
ab0975d
Merge branch 'fix/397-unknown-workflow-suggests-catalog-name' into de…
dkackman Sep 24, 2026
57750da
style(mcp): #397 - satisfy ruff format on the unknown-workflow sugges…
dkackman Sep 24, 2026
83df0e6
fix(engine): #397 - measure a close-match typo against the catalog en…
dkackman Sep 24, 2026
9fed519
Merge branch 'fix/397-close-match-suffix-typo' into develop (#397)
dkackman Sep 24, 2026
25fd20c
fix(engine): #398 - pair_audio carries a loaded video's recorded shots
dkackman Sep 24, 2026
43502d9
fix(engine): #399 - nest an input's own shots when concat_videos/diss…
dkackman Sep 24, 2026
8d240d3
Merge branch 'fix/399-nested-shots-on-join' into develop (#399)
dkackman Sep 24, 2026
0fd6043
fix(engine): #400 - refuse a dissolve_videos overlap wider than a res…
dkackman Sep 24, 2026
0a73ce3
fix(engine): #401 - round dissolve_videos' crossfade window like ever…
dkackman Sep 24, 2026
34b1be2
Merge branch 'fix/401-dissolve-crossfade-window-rounding' into develo…
dkackman Sep 24, 2026
3f1c84d
style(tests): #401 - ruff format test_shots.py
dkackman Sep 24, 2026
a22ddf2
fix(engine): #401 - derive dissolve_videos' shot start_sample instead…
dkackman Sep 24, 2026
ec53e69
Merge branch 'fix/401-dissolve-shot-sample-accumulation-drift' into d…
dkackman Sep 24, 2026
49f3749
fix(server): #402 - warn at validate time when slice_audio's source i…
dkackman Sep 24, 2026
fb4887d
Merge branch 'fix/402-slice-audio-preflight-warning' into develop (#402)
dkackman Sep 24, 2026
dce8358
feat(mcp): #403 - trim model narrative from MCP descriptions, move th…
dkackman Sep 24, 2026
007717a
Merge branch 'feat/376-a-trim-model-narrative' into develop (#403)
dkackman Sep 24, 2026
246f0dc
fix(dw): #404 - pass a live result object through get_value unchanged
dkackman Sep 24, 2026
8c6183a
Merge branch 'fix/404-sub-workflow-previous-result-passthrough' into …
dkackman Sep 24, 2026
a99d899
fix(engine): #405 - trim a nested dissolve shot's tail, derive its sa…
dkackman Sep 24, 2026
f49f78e
Merge branch 'fix/405-nested-dissolve-shot-tail-trim' into develop (#…
dkackman Sep 24, 2026
6254481
style(tests): #405 - ruff format the new dissolve shot tests
dkackman Sep 24, 2026
3ff4ff8
Merge branch 'fix/405-format-fixup' into develop (#405)
dkackman Sep 24, 2026
a2da952
test(security): browser headers, CORS and active content served on th…
claude Sep 24, 2026
2e004c2
test(security): hostile content rendered by the web UI in a real browser
claude Sep 24, 2026
682f7db
docs(proposals): #376 - design record for the MCP model-narrative trim
dkackman Sep 24, 2026
c527aba
Merge branch 'docs/376-close-out' into develop (#376)
dkackman Sep 24, 2026
96b463d
Merge pull request #391 from dkackman/test/security-gaps
dkackman Sep 24, 2026
bcca3c8
test(security): enter the probe token through the UI's own popover
claude Sep 24, 2026
868ff1a
Merge pull request #406 from dkackman/test/security-web
dkackman Sep 24, 2026
ec1d515
chore: idea template files to owner:lead (researcher role retired in …
dkackman Sep 24, 2026
911a13b
feat(mcp): #388 - assess_output route, tool, guide section and pointers
dkackman Sep 24, 2026
6c33bae
test(server): #388 - assess route, assess_output handler, metadata hi…
dkackman Sep 24, 2026
558b06e
Merge branch 'feat/378-c-assess-output' into develop (#388)
dkackman Sep 24, 2026
bfb22ba
feat(assess): #386 - settle seam_frame_jump at 25 from field runs; pi…
dkackman Sep 24, 2026
c099115
Merge branch 'feat/378-d-thresholds' into develop (#386)
dkackman Sep 24, 2026
6acbd2e
fix(pipeline_processors): #408 - fit each chain segment's own audio t…
dkackman Sep 24, 2026
09c9d6a
Merge branch 'fix/408-chain-audio-fit' into develop (#408)
dkackman Sep 24, 2026
ecf29b9
docs(proposals): #378 - close out output assessment stages 2-4
dkackman Sep 24, 2026
d635985
Merge branch 'docs/378-close-out-output-assessment' into develop (#378)
dkackman Sep 24, 2026
b4151ce
feat(security): #409 - untrusted type refs name a class, constant wal…
dkackman Sep 24, 2026
1c44efc
Merge branch 'feat/407-A-trust-gate-url-host' into develop (#409)
dkackman Sep 24, 2026
46045fa
feat(security): #409 - validate refuses constant: walks and *_dtype k…
dkackman Sep 24, 2026
9a3f629
Merge branch 'feat/407-A-trust-gate-url-host' into develop (#409)
dkackman Sep 24, 2026
97c3641
feat(security): #410 - refuse text/html and text/xml results, sandbox…
dkackman Sep 24, 2026
779778b
Merge branch 'feat/407-B-active-types-headers' into develop (#410)
dkackman Sep 24, 2026
2aef413
fix(server): #414 - run_workflow checks caller arguments' resolved co…
dkackman Sep 24, 2026
74831b6
Merge branch 'fix/414-run-workflow-content-type-arguments' into devel…
dkackman Sep 24, 2026
84ac39f
feat(security): #411 - re-check every media redirect, refuse non-glob…
dkackman Sep 24, 2026
680937f
Merge branch 'feat/407-C-ssrf-redirects-cgnat' into develop (#411)
dkackman Sep 24, 2026
32620b7
fix(server): #415 - JobManager.submit checks content_type against cal…
dkackman Sep 24, 2026
2a69bbf
Merge branch 'fix/415-run-workflow-blind-content-type-check' into dev…
dkackman Sep 24, 2026
4745d93
feat(security): #412 - listings and export zip drop symlinks escaping…
dkackman Sep 24, 2026
aede93f
Merge branch 'feat/407-D-symlink-containment' into develop (#412)
dkackman Sep 24, 2026
3215bd8
fix(worker): #415 - execute path validates against the caller's argum…
dkackman Sep 24, 2026
34acbfd
Merge branch 'fix/415-worker-execute-argument-blind-validation' into …
dkackman Sep 24, 2026
f6c127c
style: #415 - ruff format test_worker_execute.py
dkackman Sep 24, 2026
27034e5
feat(security): #413 - pixel limit before any image decode
dkackman Sep 24, 2026
5d4bfe4
Merge branch 'feat/407-E-decode-pixel-limit' into develop (#413)
dkackman Sep 24, 2026
001ec1f
docs: #407 - design record for closing the xfail security tests
dkackman Sep 24, 2026
f6180bb
Merge branch 'docs/407-closeout' into develop (#407)
dkackman Sep 24, 2026
ef55c15
chore: move preflight.sh into scripts/, runnable from anywhere
dkackman Sep 24, 2026
fe376bb
docs: 0.4.0 release notes in RELEASING.md
dkackman Sep 24, 2026
c928a15
security: check the defining module of a type an untrusted workflow r…
dkackman Sep 24, 2026
f2facac
security: confine validate-time media probes to the run's read roots
dkackman Sep 24, 2026
2a56972
security: limit untrusted type references to constructible kinds
dkackman Sep 24, 2026
db49aa3
docs: 0.4.0 notes name the untrusted type allowlist
dkackman Sep 24, 2026
db50b17
Merge branch 'fix/untrusted-gate-and-probes' into develop
dkackman Sep 24, 2026
edf826c
Merge branch 'chore/preflight-to-scripts' into develop
dkackman Sep 24, 2026
af0deaf
fix(step-cache): #418 - subtract stale entry size from _retained_bytes
dkackman Sep 25, 2026
8d6612c
Merge branch 'fix/418-step-cache-stale-eviction-bytes' into develop (…
dkackman Sep 25, 2026
cb24aad
docs: #419 - fix skill's shot-count wording, #420 - README/AGENT_LOOP…
dkackman Sep 25, 2026
7e5302f
fix(security): #422 - name search roots in sub-workflow path refusal
dkackman Sep 25, 2026
d86564b
Merge branch 'fix/422-subworkflow-refusal-search-roots' into develop …
dkackman Sep 25, 2026
70dded5
style: #422 - ruff format
dkackman Sep 25, 2026
4f84557
Merge branch 'fix/422-subworkflow-refusal-search-roots' into develop …
dkackman Sep 25, 2026
f6d438e
fix(mcp): #418 - expose step cache accounting via get_memory
dkackman Sep 25, 2026
a662b25
Merge branch 'fix/418-step-cache-observability' into develop (#418)
dkackman Sep 25, 2026
838e7c4
docs(shots): #423 - document pair_audio's last-shot sample slop
dkackman Sep 25, 2026
48b3a47
Merge branch 'fix/423-remeasured-shots-last-boundary-docs' into devel…
dkackman Sep 25, 2026
3e5ec4f
docs(shots): #423 - put the last-shot sample-slop explanation where g…
dkackman Sep 25, 2026
0040d52
docs(tasks): #424 - document pair_audio's fit argument
dkackman Sep 25, 2026
c6a69e0
Merge branch 'fix/424-pair-audio-fit-docs' into develop (#424)
dkackman Sep 25, 2026
55679c7
docs(tasks): #424 - add fps row to pair_audio's argument table
dkackman Sep 25, 2026
51ef463
Merge branch 'fix/424-pair-audio-fps-docs' into develop (#424)
dkackman Sep 25, 2026
b5917e7
fix(assess): #425 - warn on a shots record reaching past the file's end
dkackman Sep 25, 2026
70480a6
style(assess): #425 - ruff format _span_overrun
dkackman Sep 25, 2026
8f43066
fix(assess): #426 - remeasure a joined video's shots against fitted a…
dkackman Sep 25, 2026
9430c21
fix(assess): #427 - de-duplicate findings in the compact assess merge
dkackman Sep 25, 2026
7ecd1e6
Merge branch 'fix/426-427-shot-span-overrun' into develop (#426, #427)
dkackman Sep 25, 2026
baf463e
fix(result): #426 - remeasure a joined video's shots against the deco…
dkackman Sep 25, 2026
70a3462
Merge branch 'fix/426-shot-span-ground-truth' into develop (#426)
dkackman Sep 25, 2026
5639940
fix(pair_audio): #428 - fit="video" always fits and warns, not just p…
dkackman Sep 25, 2026
2b49321
Merge branch 'fix/428-pair-audio-fit-tolerance' into develop (#428)
dkackman Sep 25, 2026
2b437aa
docs(pair_audio): #428 - document the post-mux AAC drift fit doesn't …
dkackman Sep 25, 2026
d6f0562
fix(pair_audio): #429 - sub-frame fit gaps report samples, not a phan…
dkackman Sep 25, 2026
29516df
style(pair_audio): #429 - ruff format
dkackman Sep 25, 2026
0fb7e1b
fix(gallery-frames): #430 - seams reads a linked asset's recorded shots
dkackman Sep 25, 2026
8291b7f
style(test_server): #430 - ruff format
dkackman Sep 25, 2026
5a7f082
fix(ltx2-keyframes): #431 - wrap frames as explicit image media refer…
dkackman Sep 25, 2026
ae49356
fix(shots): #432 - name shots by source input, not flattened position
dkackman Sep 25, 2026
5f2a766
Merge fix/432-shot-source-index into develop
dkackman Sep 25, 2026
c9f7563
fix(variables): #433 - refuse a dict/list override of a string variable
dkackman Sep 25, 2026
b055573
Merge fix/433-dict-into-string-variable into develop
dkackman Sep 25, 2026
990b156
fix(audio-join): #435 - pad a joined track short of its frame grid
dkackman Sep 25, 2026
ab144e2
fix(audio-join): #434 - warn when match_levels gains a near-silent shot
dkackman Sep 25, 2026
e6e22c3
Merge fix/434-435-audio-join-warnings into develop
dkackman Sep 25, 2026
91970b7
style(tests): #435 - ruff format the padding-warning test
dkackman Sep 25, 2026
ce0dfd6
style(tests): #434 - ruff format the near-silent warning test
dkackman Sep 25, 2026
2dbdd43
fix(result): #435 - warn when a joined track's mux still lands short …
dkackman Sep 25, 2026
2cb28ca
test(result): #435 - cover the post-mux shortfall warning
dkackman Sep 25, 2026
297341e
Merge fix/435-mux-shortfall-warning into develop
dkackman Sep 25, 2026
ea35786
fix(server): #436 - add kinds filter to the event-log route and MCP g…
dkackman Sep 25, 2026
af90441
test(mcp): #436 - cover kinds forwarding in get_job_events
dkackman Sep 25, 2026
557ad98
fix(mcp): #437 - drop the misleading acknowledged=true instruction fr…
dkackman Sep 25, 2026
9e2eae7
Merge fix/436-437-event-log-kinds-and-workspace-refusal into develop
dkackman Sep 25, 2026
fa32d6d
fix(mcp): #438 - stop delete_workspace appending acknowledgement text…
dkackman Sep 25, 2026
117e051
Merge fix/438-delete-workspace-not-found-acknowledgement into develop
dkackman Sep 25, 2026
75fb380
style(mcp): #438 - ruff format test_mcp_workspaces.py
dkackman Sep 25, 2026
2024941
fix(server): #439 - a task-only workflow's history is comparable to a…
dkackman Sep 25, 2026
bee4d51
Merge fix/439-task-only-observed-basis into develop
dkackman Sep 25, 2026
ce7def9
fix(mcp): #441 - gate the Music 3 ceiling hint to audio outputs
dkackman Sep 25, 2026
fc2e061
fix(ltx2): #442 - drop duration_head from LTX2InContextPipeline templ…
dkackman Sep 25, 2026
f66edcd
Merge fix/442-in-context-duration-head into develop
dkackman Sep 25, 2026
73cd02e
fix(arguments): #443 - route a media_type reference through fetch_vid…
dkackman Sep 25, 2026
fe3b175
fix(video_utils): #443 - accept a bare still as a one-frame video
dkackman Sep 25, 2026
8a72bd8
Merge fix/443-frame-grid-media-type-still into develop
dkackman Sep 25, 2026
5833624
style: #443 - ruff format test_arguments.py
dkackman Sep 25, 2026
c1a00ec
fix(video_utils): #444 - loop_frames scales to [0,1] float32, not uint8
dkackman Sep 25, 2026
e569493
fix(templates): #444 - point reference-sheet's default asset at what …
dkackman Sep 25, 2026
d7c4ccd
Merge fix/444-loop-frames-scale into develop
dkackman Sep 25, 2026
50376dc
fix(server): #445 - /outputs/{name} resolves asset: references
dkackman Sep 25, 2026
3a28146
Merge fix/445-output-image-asset-ref into develop
dkackman Sep 25, 2026
34419a3
fix(server): /outputs asset: miss no longer names server paths
dkackman Sep 25, 2026
11b6dff
fix: #435 mux warning only within the fit tolerance; #436 kinds match…
dkackman Sep 25, 2026
dacbc7e
docs: #435/#426 warnings and remeasured shots, as the code now behaves
dkackman Sep 25, 2026
73cc091
docs: 0.4.0 notes cover #418-#445 and the release fixes
dkackman Sep 25, 2026
6904328
fix: #436 kinds docstring within the tool-surface budget
dkackman Sep 25, 2026
0d3a6c9
fix: #453 #454 stock joins warn only on something a caller can act on
dkackman Sep 25, 2026
23e6172
fix(security): contain run and cache paths where CodeQL can see it; n…
dkackman Sep 25, 2026
e86fc20
fix(security): probe resolves asset:/output: through their confined r…
dkackman Sep 25, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 17 additions & 8 deletions .github/ISSUE_TEMPLATE/idea-ticket.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
---
name: MCP agent-loop idea
about: An idea for a new capability or change, for the researcher agent to assess (see CLAUDE.md in the iterate repo) — not for bug reports, use "Bug report" for those.
about: An idea or feature request for the feature lead agent to design (see CLAUDE.md in dkackman/harnest) — not for bug reports, use "Bug report" for those.
title: ""
labels: ["idea", "owner:researcher"]
labels: ["idea", "owner:lead"]
---

**idea:** what capability or change this is proposing
Expand All @@ -12,10 +12,19 @@ labels: ["idea", "owner:researcher"]
**links:** any prior art, reference docs, upstream libraries, or related issues

<!--
The researcher agent reads this, researches the codebase and any links
above, and assesses complexity, feasibility, and value. It then either
rejects the idea (wontfix + reason), proposes a concrete plan to the
implementer (owner:implementer, ready to work), or parks it for human input
(owner:don + status:needs-approval). See CLAUDE.md in the iterate repo
("Ticket protocol") for the full label scheme.
The feature lead's design session reads this, researches the codebase and
any links above, and decides what it is:
- not worth doing: closed as not planned, reason in a comment;
- a single fix: handed to owner:implementer, ready to work;
- a feature: relabeled `feature`, and a versioned plan is posted and handed
to owner:don + status:plan-review.

On a plan: answer its questions in comments and swap the owner back to
owner:lead for a revision, or add status:plan-approved (Don only) to approve
it. The lead then splits it into stage sub-issues, the tester writes their
cases, and each stage is built, deployed and verified in turn.

If you already know it's a feature, replace `idea` with `feature`. The
owner label is the only signal of whose turn it is; see "Ticket protocol"
in CLAUDE.md in dkackman/harnest for the full label scheme.
-->
4 changes: 2 additions & 2 deletions .github/codeql/dw-security/DwPathSanitizers.qll
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,14 @@ private import semmle.python.dataflow.new.DataFlow
private import semmle.python.security.dataflow.PathInjectionCustomizations

/**
* Holds if `name` is a `dw.security` function that returns a path confined
* Holds if `name` is a `dw.security` (or `dw.locations`) function that returns a path confined
* to a base directory it was given.
*/
private predicate pathValidatorName(string name) {
name =
[
"validate_path", "validate_workflow_path", "validate_output_path",
"validate_prompt_path", "safe_join_path"
"validate_prompt_path", "safe_join_path", "validate_media_path"
]
}

Expand Down
79 changes: 78 additions & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,9 @@ references) are documented above in *Workflow sources* and *Type System*.
`"output:ltx2/Gyre/latest/still.png"`. The name is `<workflow identity>/<run id>/<file>`
under the output root, and `latest` in the run-id position picks the newest run that
holds the file (run ids sort by their UTC timestamp; a failed or fully-cached run holds
only a manifest and is skipped). Resolved in `realize_args` beside `asset:` (`dw/runs.py`),
only a manifest and is skipped), and `v<N>` there picks the run whose version is N
(below) - exactly that run, with no fallback to an older one. Either is a selector only
where run directories are, and the realized workflow pins both to the run id. Resolved in `realize_args` beside `asset:` (`dw/runs.py`),
against the output root `Workflow.run` activates, and confined to it
- A generated file becomes a stable input with `POST /api/assets/keep` (gallery "Keep as
asset", MCP `keep_output`): it is hard-linked, else copied, from the workspace's outputs
Expand Down Expand Up @@ -368,6 +370,45 @@ same reason - default setup cannot load a pack.
`JobManager.realized` finds the file. `exports` is a reserved workspace name:
`POST /api/jobs/{id}/export` gathers one finished job into
`<workspace>/exports/<job id>/` and `GET /exports/<job id>.zip` streams it.
- **A run has a number, and it is not derived from the listing** - a file's name
is per *step*, so four runs of one workflow write four files called
`AcornWarsCutAndScore-film.7-0.0.mp4` and the gallery drew four identical
captions: the run id told them apart but is not something anyone says out
loud, so an agent had no way to name one of them to a person. Every run now
takes an ordinal, `assign_run_version` (`dw/runs.py`) at the moment
`Workflow.run` opens the run directory, recorded as `version` in
`manifest.json` and read back by `run_versions`. Assigned once and never
recomputed, which is the point: deleting a middle run leaves a gap rather
than sliding every later number down, so "version 5" still means the same
run tomorrow. Assignment is `max(recorded) + 1` over *every* sibling
manifest, not one past the newest - run ids are chronological only to the
second, and within one second the spec digest decides the sort, which is
exactly what three quick reruns hit. The number is on disk from the moment
the run opens - a `status: "running"` manifest is written before the first
step and rewritten in full at the end - so a hard kill does not lose it and
a second process opening a run of the same workflow sees it. A run with no
recorded number (made before the field, or killed before even that first
manifest) is ranked: the unrecorded runs older than every recorded one take
the numbers beneath the lowest, later ones continue from the highest before
them. A ranked number would move when an older sibling is deleted, so
`record_run_versions` writes it into the manifest on the two write paths -
a run opening and a run directory being deleted; the listing never writes,
and a run with no manifest at all is left ranked. A gap in the numbers is
not only a deletion: a failed run or a fully cached rerun takes a number
and may have no media for the gallery to show under it. `GET
/api/gallery` and the metadata route carry `version` and `run_id`
(`run_versions` read once per identity per listing, not per file), and
`?folder=&version=` lists one run's files. The number is also a name:
`output:<identity>/v4/<file>`. The `run_start` event carries it, the job
records it (`run_version`, a `jobs.sqlite` column) and the export README and
zip download name (`<identity>-v4-<job id>.zip`) carry it too. MCP
`list_gallery` teaches the vocabulary and takes `folder`/`version`, and the
web UI reads the field only - a `v4` chip on the gallery card, the jobs list
and the job page, the run id in the gallery's detail pane. Nothing on disk is
renamed, so `output:` references, the step cache and `keep_output` are
untouched. Two limits taken deliberately: deleting the *newest* run frees
its number for reuse (the high-water mark lived in the manifest that went
with it), and the flat layout has no runs, so `version` is null there.
- **Result subfolders**: a step's `result.subfolder` (`dw/subfolders.py`) puts its files
in a subfolder of the run directory - `<run>/final/x.mp4` - by convention `final` or
`intermediate`; the engine treats no name specially and there is no default.
Expand Down Expand Up @@ -552,9 +593,45 @@ same reason - default setup cannot load a pack.
name into the JSON. An entry violation is reported at
`arguments.shots[0].num_frames`, and the rule is reported beside the field in
the catalog's `lists` block as well as in `constraints`
- **A joined video records its shots, measured** — `concat_videos`,
`dissolve_videos` and both `run_chain` returns set `AudioVideo.shots`
(`dw/shots.py`): one `{name, start_frame, num_frames, start_sample,
num_samples}` per input. The frames are partitioned, and the samples are
read off the waveform the join built, never derived from the frames, so a
shot's overrun stays visible (#385). Every other `AudioVideo` constructor
carries, rescales (`interpolate_frames`), re-measures (`pair_audio`) or
drops them, and `tests/test_shots.py` enumerates the constructor sites with
`ast`, so a new one fails until someone decides for it. `Result.save`
keeps them as plain data in `saved_shots` (path -> shots), which survives
the step cache's stripped copy. The manifest entry and `step_end` carry
`shots`, renamed `shot@<key>` from the step's `videos` references (as
`selected_field` does). `recorded_shots` (`dw/runs.py`) reads them back for
`get_gallery_metadata`'s `media.shots` and for `get_output_frames(seams=true)`
without `boundaries`. The mp4 itself carries nothing yet
- **Step cache**: a process-wide singleton (`dw/step_cache.py`) consulted by every `Workflow.run`, including server jobs; entries are keyed by `(workflow id, step name)` and validated against the output
*root*, never the per-run directory - a run directory is new every execution and would
defeat the cache; disabled entirely when the workflow sets no `seed`; a hit reports the earlier run's files with `reused: true` and writes nothing new; `memory clear` drops it. This is why "Run again" on a seeded workflow finishes instantly and generates nothing - the job page says so when every step was reused, and `POST /api/jobs/{id}/rerun` with `{"new_seed": true}` (MCP `rerun_job(new_seed=True)`) draws a fresh seed into the workflow's seed variable, which is the way to get a different image
- **Assessment probes measure a finished file and say where to look, and
decide nothing** (`dw/tasks/assess.py`, #387) - `analyze_shots`,
`analyze_seams` and `analyze_sync_drift` each read a video streaming
(thumbnails only, never the full frame list, so a long cut is cheap) and
answer a JSON dict of measurements plus `findings`, the ones that crossed a
threshold in `dw/assessment_rules.py`'s table; nothing in the engine acts
on a finding. These are the `returns: "json"` task kind, listed separately
in `list_tasks`' `assessment` (probes stay in `commands` too), and a step
on one must save `"result": {"content_type": "application/json"}` -
anything else fails validation. Shot boundaries resolve in order: the step's `shots` argument,
the video's own carried shots, the run manifest beside the file, else the
whole file as one shot (`shots_source` says which). A shot's `hard_cut:
true` field suppresses the `seam_frame_jump` rule at the seam it opens - a
cut meant as a cut. `tests/test_assessment_rules.py` pins the rules table
to real probe fields, so a rename cannot leave a rule reading nothing. `GET /api/gallery/{name}/assess` (MCP `assess_output`, #388,
`dw/server/assess.py`) runs the applicable probes in the server process on
one decode - a sync route, so it answers beside a GPU job rather than
queueing - with the shots the run's manifest (or an asset's keep sidecar)
recorded, merging `findings`/`rules_applied`/`rules_skipped` and naming
each inapplicable probe in `not_applicable`; `probe=` returns one probe's
full body and is whitelisted before the name is read.

## JSON Workflow Structure

Expand Down
19 changes: 18 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ once; without it the run fails partway through with a 401/403 from the Hub.

## Drive it from an agent

Then just ask. The agent has 58 tools covering the whole surface — the
Then just ask. The agent has 59 tools covering the whole surface — the
workflow catalog, the real diffusers pipeline signatures, the job queue, the
gallery, the model cache:

Expand Down Expand Up @@ -122,6 +122,23 @@ and outputs — so two agents, or an agent and you in the browser, share the GPU
without saving over each other. An agent calls `use_workspace` once and the
rest of the session lands there.

**Feedback from a session.** At the end of a working session, ask the agent
what got in its way: bugs, gaps, misleading skill text, tools it reached for
and couldn't find. Have it file each one as an issue on
`dkackman/diffusers-workflow` with the `field-report` label, for example:

> File each bug or gap you hit as an issue on dkackman/diffusers-workflow
> with the label `field-report`.

The label marks a report as coming from real use, not from the automated test
loop. The agent loop (see [Agent Loop](docs/AGENT_LOOP.md)) picks the report up
like any other issue when you filed it yourself; a report filed under any
other GitHub login is parked for the maintainer to review first (relabelled
`owner:don` + `status:needs-approval`), since the loop must not act
unattended on third-party text in a public repo, and is only handed to the
loop, or not, after that review. The label is also what feature planning
reads as evidence of demand.

The complete tool reference, client configuration for other MCP hosts, and the
troubleshooting table: [MCP Server](docs/MCP.md). Workspaces in depth:
[Workspaces](docs/WORKSPACES.md).
Expand Down
9 changes: 9 additions & 0 deletions docs/AGENT_LOOP.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,15 @@ of scripted MCP calls (`regression-suite-*.md` in the `iterate` repo) against
the live server and files/comments on Issues for anything that regresses. It
doesn't participate in the implementer/tester handoff.

## Outside filings

The loop runs as one GitHub login (the repo owner's) and must not act
unattended on text filed by anyone else in this public repo. An issue filed
under a different login — including a `field-report` from someone else's
session — is relabelled `owner:don` + `status:needs-approval` before either
role works it, and is handed to the loop, or not, only after the maintainer
reviews it.

## Reading a ticket

Tickets use the **MCP agent-loop ticket** issue template. Two label
Expand Down
Loading
Loading