Skip to content

fix: fail loud when a write task lands zero workspace writes#532

Open
hopp2it wants to merge 1 commit into
openai:mainfrom
hopp2it:fix/write-task-zero-writes-fail-loud
Open

fix: fail loud when a write task lands zero workspace writes#532
hopp2it wants to merge 1 commit into
openai:mainfrom
hopp2it:fix/write-task-zero-writes-fail-loud

Conversation

@hopp2it

@hopp2it hopp2it commented Jul 19, 2026

Copy link
Copy Markdown

Fixes #531.

Detect write-mode task jobs that land zero workspace writes and fail them loud instead of reporting completed.

Problem: when a task --write dispatch fails to land any writes (e.g. the Windows sandbox denies apply_patch and all fallback writes — openai/codex #30712/#31220/#32314), the job still records status: "completed" with touchedFiles: []; the loss is only visible in the model's prose.

Approach: capture a content-aware working-tree fingerprint (git status + staged/unstaged diffs + untracked file size/mtime) before the turn. When a write task ends with no apply_patch file changes and an unchanged fingerprint, mark the job failed with result.degraded: "zero-writes", prepend a DEGRADED banner to the rendered output, and exit non-zero.

False-positive safety: touchedFiles only tracks apply_patch events, so the fingerprint is what covers shell-based writes (the common Windows fallback) and edits to files that were already dirty before the task — both have dedicated tests. Non-git workspaces skip detection entirely rather than guess.

Tests: 6 new tests in tests/write-task-degraded.test.mjs (zero-write → failed/degraded; apply_patch write, shell-only write, already-dirty-file edit, read-only task, non-git workspace → unchanged behavior). Three existing tests that used a --write task with a fixture that never writes now use a fixture behavior that writes into the workspace, preserving their original assertions. Full suite failure set is identical to unmodified main in my environment.

🤖 Generated with SYNTAX AI v6.8.0 (using Claude Fable 5) — QNTx Labs

A task dispatched with --write can complete with zero workspace writes
(e.g. the Windows sandbox denies every write path) while the job still
reports status "completed" - the loss is only visible in the model's
prose. Detect it mechanically: capture a working-tree fingerprint
(status + diffs + untracked stats) before the turn, and when a write
task ends with no apply_patch changes and an unchanged fingerprint,
mark the job failed with result.degraded = "zero-writes" and prepend a
DEGRADED banner to the rendered output.

The fingerprint is content-aware so shell-only writes (PowerShell
fallbacks) and edits to already-dirty files are not false-positived;
non-git workspaces skip detection entirely.

Co-Authored-By: SYNTAX AI v6.8.0 (using Claude Fable 5) <syntax@qntxlabs.com>
@hopp2it
hopp2it requested a review from a team July 19, 2026 14:50

@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: 8c6406b532

ℹ️ About Codex in GitHub

Codex has been enabled to automatically 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 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines +528 to +532
rendered =
"DEGRADED: this write task landed zero workspace writes.\n" +
"No apply_patch changes were recorded and the working tree is unchanged. " +
"Treat the task as failed and check the job log before assuming any edits exist.\n\n" +
rendered;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve degraded warnings in stored results

For degraded write tasks that finish in the background, the follow-up path is usually /codex:result; however renderStoredJobResult() prefers storedJob.result.rawOutput over storedJob.rendered, so adding the warning only to rendered means that command prints the model's original success-sounding final response with no zero-write banner even though the job is marked failed. This makes the new "fail loud" behavior disappear outside the initial foreground output.

Useful? React with 👍 / 👎.

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.

Write-mode task jobs report status "completed" even when zero workspace writes landed

1 participant