Repository navigation
Replies: 1 comment
|
Same behaviour on the released line, not just master — so this is not master-only. On 0.1.7-rc.2 ( That matches your diagnostic: for |
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Current-version update — 2026-10-07
Rechecked on 2026-10-07 against the newest public release, 0.2.1-alpha.1, and upstream master at
5badb15009ae1756c3afe0ae0cef1faafc290ccc. The overlapping-match uniqueness fix remains applicable. The Linux filesystem/editor selection passed 84 cases with 2 explicit skips; the focused assembled headless snapshot also passed. All five product commits are preserved in the published current-baseline integration; both the full build and full lint passed.Current patch index and verification limits. No all-checks-pass, upstream acceptance or released-fix claim is made. This update is AI-assisted with Codex; the published commits retain its co-author.
The original report and its verification history are preserved below.
Summary
On master at
5badb15009ae1756c3afe0ae0cef1faafc290ccc, bothstr_replace_editorand the local filesystem's unique literal-edit path accept some ambiguous replacements. They count only non-overlapping matches even when the request requires exactly one possible target.I did not find an equivalent public report in the Discussion, Issue, PR, and indexed-repository searches performed for this audit. This does not establish that nobody has discovered it privately.
Reproduction
Create a file with these exact bytes:
Use
old_str = "item\nitem\n"andnew_str = "changed\n"withstr_replace_editor, or the equivalentctx.fs.editText()request withreplaceAll: false.The search text starts at byte offsets 0 and 5. Those starts overlap, but neither interface supplies a selection policy for choosing one.
Before the patch, the diagnostic produced:
{ "before": "item\nitem\nitem\n", "old": "item\nitem\n", "matchingOffsets": [0, 5], "nonOverlappingControlRejected": true, "actualIsError": false, "actualAfter": "changed\nitem\n", "fsLocal": { "after": "changed\nitem\n", "diskAfter": "changed\nitem\n" }, "expected": "FS_AMBIGUOUS_EDIT and unchanged file" }Expected: reject with
FS_AMBIGUOUS_EDITand leave every file byte unchanged. Ordinary, non-overlapping duplicate matches already reject; the missing case is the overlapping start.Root cause and patch
The editor advances to
match + search.length; the provider's occurrence counter does the same. Both skip a valid start inside the previous match.The patch enumerates every possible start for unique edits. Replace-all remains non-overlapping, so its count still equals actual replacements rather than possible overlapping starts. No fuzzy matching, location selector, permission bypass, public API, dependency, or Session-format change is introduced.
Verification
The pre-fix overlap regression failed because both entry paths changed the file. After the patch, LF and CRLF real-plugin tests reject both edits and preserve the file. Provider tests also preserve non-overlapping replace-all counts.
On Ubuntu 24.04 under WSL2, Node 24.19.0 and pnpm 11.7.0, the combined branch's owning suites passed 402 tests, with four unchanged platform-specific skips. All five modified production modules reached 100% statements, branches, functions, and lines. The command was:
corepack pnpm exec vitest run packages/fs/fs-local/tests/fsio.spec.ts packages/fs/fs-local/tests/filesystem.spec.ts packages/fs/tool-str-replace-editor/tests packages/session-query/session-query-sqlite/tests packages/util/native-command/tests packages/host/open-in-app/tests --coverage --coverage.include=packages/fs/fs-local/src/fsio.ts --coverage.include=packages/fs/tool-str-replace-editor/src/index.ts --coverage.include=packages/session-query/session-query-sqlite/src/index.ts --coverage.include=packages/session-query/session-query-sqlite/src/schema.ts --coverage.include=packages/util/native-command/src/desktop-entry.tsThe actual assembled
dsh --profile headlessreplay passed with deterministic model replay:One scenario and all three corpus checks passed. Both editing tools return
FS_AMBIGUOUS_EDIT, and the independent complete expected workspace comparison passes. No existing snapshot or normalizer was changed to hide an error.Full build and type-aware lint passed. The normal pre-push hook also ran the full
pnpm run typechecksuccessfully before publication to the fork. Validation counts above belong to the combined branch, not a separate upstream CI run. The full hygiene aggregate is not claimed green: 16 unchanged vendor rescope residues were reproduced on the pristine baseline. The earlier doc-sync aggregate hit a default-heap OOM; its 41 other checks passed, and the failed graph check passed separately with a 4-GB heap. The updated bilingual corpus also passed independently. These limitations do not replace the behavior regressions above.Related scope and limitations
#5033 proposes ordered batch editing, and #4934 proposes tolerant matching after a literal miss. This report changes neither operation set nor literal matching: it fixes uniqueness detection when the literal text already matches twice.
The canonical keyless scenario was generated and replayed on Linux. Windows unit tests passed, but the Linux canonical scenario was not replayed on Windows or macOS. This does not address unrelated insertion or line-ending reports.
The patch is offered as a cherry-pickable fork commit because the current contribution policy does not accept external PRs. Audit, implementation, and local verification were AI-assisted with Codex; the commit includes
Co-authored-by: Codex <noreply@openai.com>.All reactions