Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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 CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ checkpoint, and status-only commits are intentionally omitted.

### Changed

- Terminal live-proof recordings tune VP9 for realtime capture and accept the recorder once any payload is written, matching the encoder's bursty muxer output.
- OpenClaw browser live proofs run against the repository's mock control-UI dev server.
- Folder reconciliation now defers with a zero-mutation result when the open-state scan hits GitHub rate limiting, so throttled proof/apply/publish runs proceed to their close and publication work instead of failing before `Apply close proposals` can run.
- Comment-only sync now defers its remaining batch as a runtime-budget-style yield when GitHub rate limits a live read, instead of failing the scheduled run; the next 15-minute cycle resumes the interrupted item, and close-mode apply keeps its loud failure.
Expand Down
18 changes: 11 additions & 7 deletions src/live-proof/drivers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,12 @@ export function terminalCommandPlan(options: {
":99.0",
"-c:v",
"libvpx-vp9",
// Realtime tuning: default VP9 encoding cannot hold 30fps on a
// two-core hosted runner and buffers output for seconds at a time.
"-deadline",
"realtime",
"-cpu-used",
"8",
options.rawVideoPath,
],
waitAfter: "recorder",
Expand Down Expand Up @@ -347,20 +353,18 @@ function waitForRecorder(
recorderSession: string,
rawVideoPath: string,
): void {
let previousSize: number | undefined;
for (let elapsed = 0; elapsed <= RECORDER_READY_TIMEOUT_SECONDS; elapsed += 1) {
const size = recordingSize(runner, checkout, rawVideoPath);
if (recorderExited(runner, checkout, recorderSession)) {
throw new Error("recorder session exited before the raw WebM began growing");
}
if (size !== undefined) {
if (previousSize !== undefined && size > previousSize) return;
previousSize = size;
throw new Error("recorder session exited before the raw WebM was written");
}
// VP9 muxer output is bursty, so consecutive equal size samples are normal
// while recording; any written payload proves the recorder captures frames.
if (size !== undefined && size > 0) return;
if (elapsed < RECORDER_READY_TIMEOUT_SECONDS) pollSleep(runner);
}
throw new Error(
`raw WebM did not begin growing within ${RECORDER_READY_TIMEOUT_SECONDS} seconds`,
`raw WebM was not written within ${RECORDER_READY_TIMEOUT_SECONDS} seconds`,
);
}

Expand Down
6 changes: 3 additions & 3 deletions test/live-proof.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,7 @@ test("terminal driver accepts a recorder file that appears and grows late", () =
const calls: string[] = [];
const result = runTerminalFixture(
terminalLifecycleRunner(calls, {
recorderSizes: [undefined, undefined, 7, 7, 11],
recorderSizes: [undefined, undefined, 0, 0, 11],
}),
);
assert.equal(result.status, "completed");
Expand All @@ -319,7 +319,7 @@ test("terminal driver reports a dead recorder with its pane diagnostics", () =>
() => runTerminalFixture(runner),
(error: unknown) => {
assert.ok(error instanceof Error);
assert.match(error.message, /recorder session exited before the raw WebM began growing/);
assert.match(error.message, /recorder session exited before the raw WebM was written/);
assert.match(error.message, /\[xterm: .*\]\nxterm pane ready/);
assert.match(error.message, /\[recorder: .*\]\nffmpeg: cannot open display :99/);
return true;
Expand Down Expand Up @@ -457,7 +457,7 @@ test("live-proof workflow keeps execute secretless and attach trusted", () => {
assert.match(source, /uses: \.\/\.github\/actions\/create-target-write-token/);
assert.match(source, /CLAWSWEEPER_LIVE_PROOF_S3_ENDPOINT: \$\{\{ secrets\./);
assert.match(source, /setsid timeout --kill-after=30s 1500s/);
assert.match(source, /apt-get install --yes ffmpeg tmux x11-utils xvfb xterm/);
assert.match(source, /apt-get install --yes ffmpeg tmux x11-utils xfonts-base xvfb xterm/);
assert.match(source, /--record \.\.\/live-proof-report\.md/);
assert.doesNotMatch(source, /--plan \.\.\/live-proof/);

Expand Down
Loading