Skip to content

#601 stage 1: window_video task (split a long source into overlapping windows) #628

Closed

Description

@dkackman

Stage 1 of #601. It builds the plan's Stage 1: window_video (server) and the window_video design section of plan v2. If this body and the plan disagree, the plan wins.

Filed by the lead agent, model claude-opus-5-5 via anthropic, 2026-10-05.

Builds

  • A new utility task, window_video(video, index, num_frames, overlap, fps=None), which returns one AudioVideo: window index, covering source frames [i·stride − overlap, i·stride + stride) with stride = num_frames − overlap.
  • TASK_ARGUMENT_DOMAINS entries: index and overlap non-negative, num_frames positive. The task also checks them at run time.
  • The AudioVideo construction site added to tests/test_shots.py EXPECTED_SITES and to dw/shots.py's list.

Owes

  • Tests: window spans (first, middle, last); prefix and pad frames; audio spans tiling across windows at 24 and 25 fps with 44.1k and 48k audio; each refusal; a source with no audio.
  • Docs: docs/TASKS.md (Video Processing) and a docs/ARCHITECTURE.md row.

Deploy

Server restart.

Passes when

The plan's stage 1 acceptance intent holds over MCP. With a ~50-frame asset: clip, num_frames=17 and overlap=4: index=0 gives 17 frames whose first 4 match frame 0 and whose first 4 frames of audio are silent; index=3 gives 17 frames whose last 2 repeat frame 49; index=4, overlap=17 and a negative overlap are refused. The stage also passes every pending: #<this issue> case the tester writes.

Activity

  1. added
    featureWork bigger than a fix: designed with Don, built in stages (harnest R11)
    owner:leadFeature lead's turn (harnest R11)
    stageA child issue: one stage of a feature
    on Oct 5, 2026
  2. added and removed
    owner:leadFeature lead's turn (harnest R11)
    on Oct 6, 2026
  3. dkackman commented on Oct 6, 2026

    @dkackman
    OwnerAuthor

    Stage 1 built and deployed (lead, claude-opus-5-5 via anthropic)

    Shipped: 9015a5e1 (branch feat/601-A-window-video), merged to develop as a83ad1cc. Deploy: [deploy 06:16:13] deployed develop @ a83ad1cc, healthy after 6s, mcp=true. The server was restarted.

    Plan items covered:

    • Task. window_video(video, index, num_frames, overlap, fps=None) is in the new module dw/tasks/windows.py, registered with assessment=False.
    • Refusals.
      • overlap >= num_frames, overlap < 0 and index < 0 are refused at run time.
      • index·stride >= source_frames is refused at run time. The message names the source frame count and the last valid index, (total-1)//stride.
    • Domains. TASK_ARGUMENT_DOMAINS["window_video"]: index ≥ 0, num_frames > 0, overlap ≥ 0, fps > 0. The same check runs again at run time through check_arguments.
    • Shot sites. ("dw/tasks/windows.py", "window_video"): ("none", 1) is added to EXPECTED_SITES, and the dw/shots.py docstring now mentions it.
    • Tests. The new file tests/test_window_video.py covers:
      • first, middle and last spans, using the plan's 50/17/4 example;
      • prefix and pad frames;
      • stride tiling of the audio at 24/25 fps × 44.1k/48k;
      • silent prefix and pad;
      • each refusal, both at run time and through validate;
      • a source with no audio, which gives a window with audio=None;
      • a real-path test: an encoded mp4 goes through realize_args, then the task, and comes out with its audio.
    • Docs. A ### window_video section in docs/TASKS.md (Video Processing), plus a row in its command table. A new "Overlap windows of a long video" row in docs/ARCHITECTURE.md.

    Deviations, so they don't read as bugs:

    1. Static check on overlap. validate_workflow refuses a literal overlap >= num_frames itself, through a cross-argument check in task_domains.window_video_errors, not only at run time. The plan allowed either. The index-past-end refusal stays run-time only, because the source's length isn't known at validate time.
    2. How video is read. A key named video is normally loaded as bare frames, which would strip an asset:/output:/path source of its audio. So window_video joins _LAZY_FRAME_COMMANDS in dw/arguments.py: a file source reaches the task as a VideoFileReference, and the task reads it with load_audio_video. Two consequences:
      • An earlier step's video (previous_result:) is used as it is, audio included when it has one.
      • An http(s) URL source still goes through the eager frames-only fetch, so its window is silent. This is documented in TASKS.md.
  4. dkackman commented on Oct 6, 2026

    @dkackman
    OwnerAuthor

    Architecture review queued by the loop driver: this hand-off changed dw/ or dw_mcp/ on develop (2e8fced048..a83ad1ccb4: dw/arguments.py dw/shots.py dw/task_domains.py dw/tasks/task.py dw/tasks/video_utils.py dw/tasks/windows.py). The reviewer checks it against docs/ARCHITECTURE.md before the tester verifies.

  5. added
    owner:leadFeature lead's turn (harnest R11)
    and removed on Oct 6, 2026
  6. 2 remaining items

  7. added 2 commits that reference this issue on Oct 6, 2026
  8. added and removed
    owner:leadFeature lead's turn (harnest R11)
    on Oct 6, 2026
  9. dkackman commented on Oct 6, 2026

    @dkackman
    OwnerAuthor

    Architecture bounce resolved; stage 1 redeployed (lead, claude-opus-5-5 via anthropic)

    Shipped: 94231fb2 on feat/601-A-window-video, merged to develop as 6b6da603. Deploy: [deploy 06:53:01] deployed develop @ 6b6da603, healthy after 6s, mcp=true. The server was restarted.

    Fix for Finding 1: _window_audio in dw/tasks/windows.py now cuts the real span with dsp.slice_samples(waveform, f2s(real_start), f2s(real_end) - f2s(real_start)). The hand-rolled short padding is gone, so dw/dsp.py is the only place that does frame-aligned slicing and zero-padding. The head and tail silence for the synthetic frames hasn't changed. The behavior is the same: TestAudio::test_strides_tile_the_source_track_exactly and the rest of tests/test_window_video.py pass without changes. The full suite has 8758 passed, 16 skipped and 1 xfailed, and ruff is clean.

    Plan items and deviations: these are the same as in the first hand-off comment. The overlap check is static as well as run-time, and window_video joins _LAZY_FRAME_COMMANDS so a file source keeps its audio. No MCP shape changed.

  10. dkackman commented on Oct 6, 2026

    @dkackman
    OwnerAuthor

    Architecture review queued by the loop driver: this hand-off changed dw/ or dw_mcp/ on develop (29457326d0..6b6da603c1: dw/tasks/windows.py). The reviewer checks it against docs/ARCHITECTURE.md before the tester verifies.

  11. dkackman commented on Oct 6, 2026

    @dkackman
    OwnerAuthor

    Architecture review: passed (reviewer, claude-opus-5-5 via anthropic)

    What I read: git diff 29457326..6b6da603 -- dw dw_mcp (commit 94231fb2). The only file it touches is dw/tasks/windows.py. I checked it against docs/ARCHITECTURE.md and item 3 of docs/stabilization/harness/stage-c-guardrails.md.

    Finding 1 (second owner, dw/dsp.py): resolved. _window_audio now gets the real span from dsp.slice_samples(waveform, f2s(real_start), f2s(real_end) - f2s(real_start)). The hand-rolled short padding is gone, so the zero-padding rule lives only in dsp.py. The head and tail silence for the synthetic frames is unchanged, as the bounce allowed.

    No new findings:

    • Second owner: none.
    • Build vs. buy: none.
    • Map: no new module and no new owner. The "Overlap windows of a long video" row from the first hand-off still covers this.
    • Context: no CLAUDE.md changed.

    The first review covered the rest of the original change (2e8fced0..a83ad1cc) and found nothing else.

    Waived: nothing. #628 has no arch-approved label.

    Not checked: I didn't run the tests or scripts/arch_metrics.py. They're left to CI and the hook. The tester's MCP verify comes next.

  12. dkackman commented on Oct 6, 2026

    @dkackman
    OwnerAuthor

    Verified over MCP against lem develop @ 955c519 — tester, claude-opus-5-5 via anthropic.

    Surface: list_tasks lists window_video under commands; get_task shows index/overlap non_negative, num_frames/fps positive.

    C-F226 — PASS (asset:qa-cast/ep6-cold-open.mp4, 124 f, 24 fps, 32 kHz stereo; num_frames 17, overlap 4)

    • index 0 (job bdc0959a1308): 17 frames, 960×544, 0.708 s, 32 kHz/2ch. Frames 0–3 = source frame 0, analyze_audio on frames 0–3 all null (digital silence). Window frames 4–16 vs source 0–12: peak −5.2307/−5.2307, RMS −19.7283/−19.7280 dB.
    • index 5 (job af668b2f0318): 17 frames; frame 0 ≈ source 61, frame 16 ≈ source 77.
    • index 9: 17 frames; frame 0 ≈ source 113, frame 10 ≈ source 123, frames 11–16 repeat 123; pad audio all null; frames 0–10 vs source 113–123: peak −16.0437/−16.0437, RMS −29.3702/−29.3699 dB.

    C-F227 — PASS

    • arms 2, 3 (overlap 17, 20): refused at validate_workflow, path overlap, "needs 'overlap' below 'num_frames'".
    • arms 4, 5, 6 (overlap −1, index −1, num_frames 0): refused at validate with domain errors.
    • arm 1 (index 10): passes validate, refused at run start (job 9344e7bf9629, empty manifest): "window 10 would start at source frame 130, but the source has 124 frames - with num_frames 17 and overlap 4 the last window is index 9 (10 windows)".
    • arm 7 (35/4/index 4): refused at run start (job 20da0b5bf7c4, empty manifest), "…last window is index 3 (4 windows)".
    • accepted arms (job 6bbb15611d5b): a8 35/4/3 → 35 frames, frame 0 ≈ source 89, frame 34 ≈ source 123; a9 17/16/123 → 17 frames, frame 0 ≈ source 107, frame 16 ≈ source 123; a10 17/0/0 → 17 frames, frames 0 and 1 = source 0 and 1 (distinct).

    C-F228 — PASS (job 7a62de571f20, window_video over previous_result: of video_frames): 17 frames, 960×544, 24 fps, get_gallery_metadata reports no audio stream; frames 0–4 = source frame 0, frame 16 ≈ source 12.

    Removed the pending: #628 lines from C-F226/C-F227/C-F228 in harnest's regression-suite-complete.md; they are ordinary cases now.

    Unrelated, filed separately: get_output_frames returns HTTP 500 when at holds a video's last two adjacent frames.

  13. added
    status:verifiedTester confirmed the fix via a real MCP call
    and removed on Oct 6, 2026
  14. added a commit that references this issue on Oct 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    featureWork bigger than a fix: designed with Don, built in stages (harnest R11)owner:testerTester's turn to actstageA child issue: one stage of a featurestatus:verifiedTester confirmed the fix via a real MCP call

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions