Skip to content

[split-1066] U5 - fix(write-to-file): capture the streaming failure once and report it once #1935

Description

@easonLiangWorldedtech

Unit U5 of the PR #1066 split (3/6).

Split plan: #703
PR: #1930
Content source of record: tag pr1066-source = 46d1d218701f0ce2d675b1b315489bacb6b0f77d (easonLiangWorldedtech/Zoo-Code).

Unit contract

handlePartial() captures the streaming failure once and reports it once — no duplicate error bubble; the authoritative execute() error is the one surfaced.

Why this unit exists on its own

Single provider group + single gate scope (streaming failure capture and its single reporting point).

Boundary

Files and budget

  • src/core/tools/WriteToFileTool.ts +38/-13 — content subset of source
  • src/core/tools/__tests__/writeToFileTool.spec.ts +229/-3 — content subset of source
  • budget: 283 a+d / 2 files — UNDER-SOFT
  • mutation gate: 24 changed executable lines — under the 500 cap; valid mutants for the whole PR are 116 / 400, so no directive was added by this unit.

Verification (must pass by once, binary)

  • zdt split verify --contract U5.json --worktree <wt> --head 4b23b6a270aa — PASS (every changed file is a content subset of the source of record, or an explicitly sanctioned allowNew file).
  • Tests: 239 passed / 5 skipped, exit 0 (narrowest relevant suites: Task.spec.ts, writeToFileTool.spec.ts, writeToFileTool-partial-state-cleanup.spec.ts, removeClineFromStack-delegation.spec.ts, presentAssistantMessage-custom-tool.spec.ts).
  • Changed-line coverage: 13 covered / 0 uncovered — PASS.
  • ESLint --prune-suppressions --max-warnings=0: clean on every touched file; suppression counts unchanged.
  • No .changeset file, no CHANGELOG edit (AGENTS.md).

Deviations recorded

  • The test reports a filesystem error only once across the streaming and execute phases was re-attributed from U5 to U6: it asserts the execute() error-path restructure, so it cannot pass at U5.

Reproduce

git fetch https://github.com/easonLiangWorldedtech/Zoo-Code p1066/u5-streaming-failure-capture
node zdt.mjs split verify --contract U5.json --worktree <wt> --head 4b23b6a270aa
node zdt.mjs split measure --worktree <wt> --base 52699c6cdc7d --head 4b23b6a270aa
pnpm --dir src exec eslint --prune-suppressions --max-warnings=0 <touched file>

Activity

  1. easonLiangWorldedtech commented on Oct 10, 2026

    @easonLiangWorldedtech
    ContributorAuthor

    Unit-scope debt for U5, registered rather than swept, so the next round can find it.

    Same defect class as commit 9c54765 (unchecked boolean results on a rollback path), still open at these call sites in the diff-view provider: the save in showEditedFileWithoutDisruptingFocus; the three applyEdit calls in saveChanges and its append and final-edit paths; the save in saveChanges; the save in keepOrCloseEditedFile. Acceptance for each: a false result propagates or is justified where the buffer can still hold unsaved content, with a test that fails when the check is removed, and the fix reuses the existing callee-owned contract instead of adding another inline check.

    Second item: the cancellation guards in handlePartial cover the four await boundaries that exist today. Any await added between acquiring per-task partial state and opening the diff view must be followed by a cancellation re-check and a state release, mirroring the two-window shape used for the stream-failed guard.

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

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions