Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
d17ba48
Make the clip folder reveal tests independent of xdg-open
claude Nov 4, 2026
4a3120a
Keep comparisons and cut detection of outside footage on this computer
claude Nov 4, 2026
3aeea82
Send the CLI's requests to this computer directly when a proxy is set
claude Nov 4, 2026
29153b4
Make Find existing Deadline job work
claude Nov 4, 2026
d452db3
Reject Deadline receipts whose IDs could name paths outside the attempt
claude Nov 4, 2026
34e90ec
Record wrong-shape Deadline receipts as invalid instead of stopping s…
claude Nov 4, 2026
541377d
Discard a crashed save's rollback journal with the old working copy
claude Nov 4, 2026
c7fd10a
Unpack the stored document before a capture saves it
claude Nov 4, 2026
97d0d1e
Keep referenced previews whose names hold spaces or accents when pruning
claude Nov 4, 2026
0899184
Escape project IDs and numbers where the studio builds HTML
claude Nov 4, 2026
7f3b1b5
Let run_spool.bat start Spool with the portable build's Python
claude Nov 4, 2026
4974b09
Publish review proxies, posters and waveforms only when complete
claude Nov 4, 2026
038e695
Quote apostrophes in the MP4 export's concat list
claude Nov 4, 2026
3870896
Save the draft before deleting takes from disk
claude Nov 4, 2026
eb60e09
Keep a retried Deadline task's copy from becoming a new take
claude Nov 4, 2026
9609c16
Skip a project folder that cannot open instead of failing every project
claude Nov 4, 2026
3635fdd
Give confirmed maintenance runs a private working copy
claude Nov 4, 2026
747e3a7
Register project folders in one transaction
claude Nov 4, 2026
83fcc93
Point the import registration tests at register_folder
claude Nov 4, 2026
00d9fc8
Stop URL-decoding stored paths a second time
claude Nov 4, 2026
ad98c6e
Encode file names in the studio's media addresses
claude Nov 4, 2026
1367b09
Refuse Comfy Cloud workflows whose result is an image
claude Nov 4, 2026
2cd8b32
Refuse unreadable media with a 400 and remove the upload
claude Nov 4, 2026
de1e5f2
Contain paths under a root that ends in a separator
claude Nov 4, 2026
3e12fc6
Report an unreadable CLI command file as a JSON error
claude Nov 4, 2026
d6b129a
Release the previous timeline download link on a new export
claude Nov 4, 2026
c3a567e
Key cached waveforms by the audio's size and modification time
claude Nov 4, 2026
ea9d6e5
Start from a checkout too shallow to have ComfyUI's folders above it
claude Nov 4, 2026
c1a54bd
Create the saved Cloud key file private from the start
claude Nov 4, 2026
5c33971
Correct three docs that contradict the code
claude Nov 4, 2026
495e1b9
Add the 2026-11-04 full audit report
claude Nov 4, 2026
d456e7f
Reject a farm receipt without a job id instead of stopping the scan
doubletwisted Nov 4, 2026
4a486cd
Skip an open project folder that was upgraded since it opened
doubletwisted Nov 4, 2026
83ac7a2
Reject authored evidence references before publishing projects
doubletwisted Nov 6, 2026
ad02e58
Validate queued inputs before freezing and allocate portable clip fol…
doubletwisted Nov 6, 2026
cb04329
Fix portable media, snapshot polling and linked input choices
doubletwisted Nov 7, 2026
2771443
Remove partial inputs and exports when writing fails
doubletwisted Nov 7, 2026
7c673a9
Report the effective Cloud key source and pin publishing action
doubletwisted Nov 7, 2026
a424ca0
Validate source clocks and drain Cloud observations safely
doubletwisted Nov 7, 2026
bafbb84
Keep maintenance and render recovery safe under concurrency
doubletwisted Nov 7, 2026
cbaa199
Handle invalid requests and collection failures safely
doubletwisted Nov 7, 2026
73d084e
Protect startup, imports and timeline rendering
doubletwisted Nov 7, 2026
9525cdc
Clean empty imports when cache path setup fails
doubletwisted Nov 7, 2026
bb54ea4
Verify draft-safe deletion and completed timeline downloads
doubletwisted Nov 7, 2026
e70d2fd
Reject malformed edit containers before preparing inputs
doubletwisted Nov 7, 2026
ba1bf5c
Keep many-cut imports bounded without slowing seeking
doubletwisted Nov 7, 2026
e155591
Keep cancellation reads and FFmpeg errors reliable
doubletwisted Nov 7, 2026
cf37734
Keep comparison frames private and retry OTIO publication
doubletwisted Nov 7, 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
1 change: 1 addition & 0 deletions .comfyignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ pages/
promo/
.native-test/
docs/archive/
docs/audits/
__pycache__/
*.pyc
AGENTS.local.md
Expand Down
3 changes: 2 additions & 1 deletion .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ jobs:
if: github.repository_owner == 'doubletwisted'
steps:
- uses: actions/checkout@v4
- uses: Comfy-Org/publish-node-action@main
# Reviewed upstream main on 2026-11-07; re-review before updating.
- uses: Comfy-Org/publish-node-action@d2366e7abb6ab16f3bb03e3520ae25c8cf749bc9
with:
personal_access_token: ${{ secrets.REGISTRY_ACCESS_TOKEN }}
148 changes: 148 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,154 @@
All notable changes to Spool are recorded here. Versions follow
[semantic versioning](https://semver.org/).

## Unreleased

### Tests

- Native browser checks cover permanent take deletion with pending and failed
saves, plus completed OTIO downloads and export failures. They verify project
revisions, retained file bytes, downloaded timelines and blob URL replacement.

### Fixes

- OTIO export retries transient Windows sharing denials and removes only its own
unfinished file if writing or publication fails.
- Comparison sheets use temporary frames that are cleaned after success or
failure. Saved sheets and explicitly exported frames remain available.
- FFmpeg errors retain Unicode filenames on Windows instead of failing while
decoding diagnostics during audio preparation, export or cut detection.
- Cancellation preflight reads avoid writer locks and checkpoint rewrites;
cancellation plans and delivery acknowledgements keep their transactions.
- Footage with many cuts imports without Windows command or FFmpeg expression
limits, while keeping exact shot frames and short keyframe intervals for seeking.
The existing FFmpeg/ffprobe 5.1 minimum is documented.
- Save and capture validate clip, take and workflow containers before staging
input files, returning request errors for invalid types. Demo save and take
validation replies include matching error codes.
- Unresolved-save messages also apply to pending actions such as take deletion.
- Transition buttons escape project track values, preventing a crafted track
from executing script when the timeline opens.
- Failed imports remove only their own new working cache, preserving existing or
redirected caches and the original import error when cleanup is denied. Cache
path setup failures also remove the import's empty destination.
- Storage reports include project backups from their managed cache directory.
- Slow launcher settings, startup-file scans and process creation run in workers,
keeping the host responsive. Delayed state updates preserve newer startup
reservations, and cancellation waits for an in-flight launch to finish.
- Local, Deadline and Cloud collection own their temporary files, so concurrent
collectors cannot overwrite or remove each other's unfinished copies.
- Finding an existing Deadline job reports an unavailable service with a retry
action when its recovery lookup fails.
- Missing required revision/request fields return validation errors before the
operation starts, including the save and take actions simulated by the demo.
- Manual reconciliation and background collection serialize work for each
project, preventing duplicate artifact copies. Shutdown waits for collection
workers to finish before releasing ownership.
- Deadline submission grace no longer includes time waiting in the queue or
preparing inputs, so old queued takes can still be submitted.
- Maintenance dry runs scan a private snapshot, so a long report does not block
another editor's save on Windows.
- Invalid or nonfinite probed frame rates produce a clear validation error.
- Cloud observation batches settle before reporting failures; cancellation
preserves other errors and always releases executor ownership on shutdown.

- The local demo server rejects inverted or out-of-bounds byte ranges with a
complete 416 response instead of a negative content length.

- Cloud key status follows the effective saved or environment credential,
including empty or whitespace-only values.
- Registry publishing pins its external action to a reviewed commit.

- Failed input staging and export muxing remove their own partial files while
preserving published inputs, successful exports and the original error.

- Linked Comfy image-loader choices refresh when a workflow opens or reloads,
keeping valid staged images selectable without changing the saved input.
- Newly described image/video dimensions follow EXIF and display-matrix
orientation. Existing media records and originals are unchanged.
- Path-imported video copies keep project-relative original references, so
moving a project also preserves its shot and audio source references.
- Joined extension audio follows the measured frame shift and sequence frame
rate, keeping its duration aligned with the joined video.
- Snapshot publications carry an identity inside the SQLite snapshot, so
same-size saves with coarse timestamps do not hide newer revisions.
- Demo take deletion follows host media-pool and generation-input protection
rules and removes aliases of a deleted original.

- New clip output folders stay distinct when names differ only by case, and
Windows device names and truncated trailing spaces/dots are made portable.
Existing assigned output folders are preserved.
- Queue preparation validates every item and source before freezing inputs,
so an invalid later item does not leave copies from earlier items.

- Authored JSON that impersonates a project evidence blob is rejected before
saving, so an imported value cannot leave the project unreadable.

- Comparing takes and detecting cuts in a take whose original lies outside the
project and Comfy folders now answer only this computer, as downloading that
original already did. Another machine could otherwise read frames of any image
or video on the Spool computer.
- `python -m spool` agent commands reach a Spool on this computer directly when
`http_proxy` is set for other traffic, instead of failing through the proxy.
- **Find existing Deadline job** works again. It failed on every call, so a
Deadline render whose submission was uncertain could not be resolved.
- A Deadline receipt whose artifact or execution ID is not the ID Spool's worker
writes is rejected. A forged ID could make collection copy a file outside the
project.
- A Deadline receipt that is valid JSON of the wrong shape is recorded as invalid
instead of stopping collection of every later receipt and project.
- Reopening a project after Spool stopped in the middle of a save restores the
last published snapshot. The interrupted save could be rolled into the fresh
copy and, on the next save, undo work published from another computer.
- Applying a workflow or using a take no longer stores another copy of the
project's workflows each time. Repeated without a save in between, it grew the
project until it could not be opened.
- `python -m spool prune --confirm` no longer removes previews the edit uses when
their file names contain spaces or accented letters.
- Opening a project no longer runs script hidden in its clip, take or media IDs,
take numbers or track numbers. The studio now escapes them like names, so an
imported project or shared project folder cannot act as the studio.
- `run_spool.bat` finds Spool with the Windows portable build's Python, whose
`._pth` file leaves the Spool folder off Python's module path.
- Importing footage again after an interrupted import works. A review copy, poster
or waveform cut short by a timeout or a stopped Spool was kept and reused, so
that file could never be imported again.
- MP4 export works for a Windows account whose name contains an apostrophe.
- **Delete from disk** saves your edits first. An edit not yet saved was replaced
by the reply, and one still saving made the delete report a conflict.
- A Deadline task that the farm retried no longer adds its second render to the
clip as an extra take; the accepted result stays the only take.
- A project folder Spool cannot open, such as one a newer Spool upgraded, is
listed as unavailable instead of stopping the project list and every other
project's renders. A folder whose upgrade fails is retried less and less often,
not every few seconds with a new backup each time.
- `python -m spool prune --confirm` and `reclaim --confirm` keep their working copy
in a private temporary folder and remove it afterwards. Another user of the
computer could plant a database at the shared path they used, which a run then
published into the project.
- Projects created, opened or imported at the same moment all stay in the project
list. One could drop another from the list, leaving its folder unreachable.
- Files whose names contain a percent sign followed by two hex digits, such as
`a%41.mp4`, play, export and collect. Their names were decoded a second time
and pointed at a different file.
- The studio shows footage whose file name contains `#`, `?` or `%`, such as an
imported `Take #3.mp4`. Its address was cut at that character.
- A Comfy Cloud workflow whose result is an image is refused before it renders.
Cloud results are collected as video, so the paid render could never arrive.
- Importing a file that is not readable media says so and keeps nothing, instead
of a generic server error with the file left in the project.
- A project folder at the root of a drive or network share (`E:\`,
`\\nas\projects\`) can use its media. Every path in it was refused as outside
the project.
- `python -m spool command` reports a missing or invalid `--file` as a JSON error
(`invalid_request`) instead of a Python traceback.
- A waveform is drawn again when its audio file is replaced at the same path,
instead of showing the old sound.
- Standalone Spool starts, and its Comfy connection status loads, from a checkout
close to the drive root such as `C:\Spool` or `/opt/spool`.
- On macOS and Linux the saved Comfy Cloud key file is private from the moment it
is written; it was briefly readable by other users of the computer.

## 0.1.1 (2026-11-03)

### Directing tools
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ review takes and change the edit there; generating takes needs Spool with ComfyU
- ComfyUI 0.39.0 or newer (tested with 0.43.1 / frontend 1.57.4 on Windows,
and 0.43.0 / frontend 1.57.4 on Apple Silicon)
- Python 3.11 or newer
- `ffmpeg` and `ffprobe` on the PATH of the process running ComfyUI (on macOS,
- `ffmpeg` and `ffprobe` 5.1 or newer on the PATH of the process running ComfyUI (on macOS,
Spool also finds a Homebrew or MacPorts install)
- For Comfy Cloud: a Comfy API key

Expand Down
Loading
Loading