Skip to content

Fix the defects found reviewing PRs #3–#17 - #18

Merged
Tom-R-Main merged 3 commits into
mainfrom
fix/review-findings
Sep 24, 2026
Merged

Tom-R-Main merged 3 commits into
mainfrom
fix/review-findings

Conversation

@Tom-R-Main

Copy link
Copy Markdown
Owner

Review: three fresh-context read-only reviewers looked at the diff 2f99df0..ca16917, one each on transport and security, the recording pipeline, and scene state. They all ran on the same model as the session. I checked every finding against the code; the obs-websocket and OBS sources on GitHub settled the two the reviewers couldn't verify. This PR fixes all of them. Every new test fails against the previous code: I swapped in each of the 11 fixed files from main and ran its tests.

Control and HTTP

  • The control lease did nothing between 2025-era HTTP clients. The SDK's stateless fallback builds a fresh server for each request, and that server never sees a client name, so every client was the same "unidentified" caller. Clients can now name themselves with ?client= in the URL (passed as authInfo, which reaches tools as ctx.http.authInfo in both protocol eras; tested). Unnamed clients cannot claim control and are refused while another client holds it.
  • obs-release-control and obs-control-status read their arguments as the request context. On stdio a holder could not release control.
  • HTTP responses now use stream.pipeline, so a stream error cannot crash the process.

Takes and recording

  • Concurrent obs-take-start calls both succeeded and orphaned a monitor. The slot is now reserved before the first await.
  • StopRecord answers before the file is finished. This is obs-websocket's own TODO in RequestHandler_Record.cpp. The stop now waits for RecordStateChanged STOPPED, up to 10 s, before inspecting.
  • Recorded tracks now follow OBS's frontend. Simple mode uses SimpleOutput/RecTracks, except at stream quality or FLV. Advanced FFmpeg recording uses FFAudioMixes. Loudness is measured on every audio stream.
  • Pause is left out of take times, and audio heard while paused is not flagged.
  • The take lock now also refuses SetOutputSettings. obs-record-clip refuses chapters at or after the end.
  • Confirmation now covers obs-stop-output/obs-toggle-output and StopOutput/ToggleOutput. confirm: true is ignored when the client can ask the user itself.

Trim

  • Control characters in chapter names no longer break or forge chapters.
  • Exports go to a temporary name and are renamed only on success.
  • An existing output, or a dangling symlink at the output path, is refused.

Scenes and snapshots

  • Restore order was wrong for many rearrangements (184 of 870 in the reviewer's simulation), and items added since were pushed to the top. Now the surviving saved items go back into the positions they occupy, in saved order, and every item is set bottom to top.
  • obs-apply-scene with order: true did not converge when an unlisted item sat above listed ones. It now moves each listed source to the front, in order. A new test covers every starting order of 4 items.
  • Transforms compare as OBS stores them. Values are 32-bit floats, and positions are rounded to half a pixel: live, 204.37 read back as 204.5. The fake OBS now does the same.
  • obs-apply-scene refuses duplicate names and scene names, snapshots every existing input it touches, and lists what was created when a creation fails partway.
  • A deleted scene no longer blocks restoring the other scenes.
  • Snapshot writes use a lock file, and an unreadable file is moved aside instead of overwritten. Automatic snapshots are capped at 10, separately from a user's 20.

Smaller

  • Tool-group tools are read-only toward OBS.
  • A subscription added during the handshake is re-sent once OBS answers.
  • Renaming a scene notifies the old items URI.

Tests

  • npm run check passes: 233 unit, 14 e2e.
  • The HTTP e2e test now covers a 2025-era client named by ?client=.

Live (OBS 32.2.2)

  • The read-only suite passes (6 passed, 2 skipped).
  • obs-apply-scene with decimal transforms converges in one call, and the automatic snapshot restored the original.
  • The "Demo" order was reversed, then restored in two moves and verified.
  • A 3 s silent take stopped via the STOPPED wait: file verified at 3.0 s, −91 dB. The test recording was deleted.

Deliberately left: the reconnect backoff is one step behind, which is harmless.

🤖 Generated with Claude Code

https://claude.ai/code/session_01Vjn8uBEa4mJshaQU3pFuqX

Control and HTTP:
- The control lease did nothing between 2025-era HTTP clients: each request
  reaches a fresh server without a name, so every client was the same
  "unidentified" caller. A client can now name itself with ?client= in its
  URL; an unnamed client cannot claim control and is refused while another
  client holds it.
- obs-release-control and obs-control-status read their arguments as the
  request context, so a holder could not release control on stdio sessions.
- HTTP responses are piped with stream.pipeline, so a failed stream cannot
  crash the process.

Takes and recording:
- Two takes started at once both succeeded and one monitor ran forever; a
  start now reserves the slot first.
- StopRecord answers before OBS finishes the file (obs-websocket's own TODO);
  stopping now waits for the STOPPED state before inspecting it.
- Simple mode records SimpleOutput/RecTracks, and Advanced FFmpeg recording
  FFAudioMixes; silence checks now follow them and measure every audio track.
- Paused time is left out of take times, and audio heard while paused is
  not reported.
- The take lock also refuses SetOutputSettings.
- obs-record-clip refuses chapters at or after the clip's end, which kept
  it recording past its length.
- Live-action confirmation covers obs-stop-output/obs-toggle-output and
  StopOutput/ToggleOutput, and ignores confirm: true when the client can ask.

Trim:
- Control characters in chapter names no longer break or forge chapters in
  the exported file.
- Exports go to a temporary name and are renamed on success, so a failure
  leaves no partial copy; an existing or dangling-symlink output is refused.

Scenes and snapshots:
- obs-restore restored the wrong order when several items moved (184 of 870
  arrangements), and pushed items added since to the top.
- obs-apply-scene order: true did not converge when an unlisted item sat
  above listed ones; it now moves each listed source to the front in order.
- Transforms compare as OBS stores them: 32-bit floats, and positions
  rounded to half a pixel (observed live).
- obs-apply-scene refuses duplicate names and names of scenes, snapshots
  every existing input it touches, and reports partial creation.
- A deleted scene no longer stops restoring the others.
- Snapshot writes take a lock file, an unreadable file is moved aside, and
  automatic snapshots are capped separately from a user's.

Also: tool-group tools are read-only toward OBS, a subscription added
during the handshake is sent once OBS answers, and renaming a scene
notifies the old items URI.

Every new test fails against the previous code.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Vjn8uBEa4mJshaQU3pFuqX
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 24, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-09-24T05:49:06.907062Z 87be9c5 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 87be9c5c78

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/tools/trim.ts Outdated
Comment thread src/tools/snapshots.ts
Tom-R-Main and others added 2 commits September 24, 2026 01:50
- The temporary export name was derived from the output name only, so a
  recording named like it (.clip.partial.mp4 exported to clip.mp4) was the
  temporary file and was deleted afterwards. The name is now unique.
- Positions compared within half a pixel, so a real half-pixel move was
  treated as no change and never restored. Both values are now rounded to
  the half pixel and compared exactly.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Vjn8uBEa4mJshaQU3pFuqX
- obs-trim-take and obs-contact-sheet pass the tool call's abort signal
  (ctx.mcpReq.signal) to ffprobe and ffmpeg, so a cancelled call stops them
  instead of leaving them running for up to 10 minutes.
- A failed connection attempt no longer also schedules a retry from the
  disconnect handler with the previous attempt count; the attempt schedules
  its own once it has counted the failure.
- The HTTP e2e test checks that a foreign Origin header is refused, and the
  README says that without OBS_MCP_HTTP_TOKEN any local program can control
  OBS through the server.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Vjn8uBEa4mJshaQU3pFuqX
@Tom-R-Main
Tom-R-Main merged commit fb6d122 into main Sep 24, 2026
4 checks passed
@Tom-R-Main
Tom-R-Main deleted the fix/review-findings branch September 24, 2026 06:02
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