Zerowidth CleanerAll measured guides

CLAUDE WATERMARK REMOVER · PRACTICAL TEST

Can deleting a marker activate a filesystem parent segment?

Yes in our explicit Node POSIX path test. safe/.. + U+200B + /private.txt stays a named segment before cleanup; afterward normalization returns private.txt and joining drops safe.

Tested October 10, 2026 · v24.19.0 · 4 measured runs

Open the Claude text cleaner · Full measured data

Code-point comparison for Marked parent

Measured inputs and outputs

These are locally constructed test strings, not evidence that Claude inserts these characters. We executed the saved homepage script snapshot with a minimal DOM harness and compared exact strings. The invisible-checkbox state and dash mode appear in each row. The observations below test this page's specific question. Destination observations run independently on the exact input and cleaned strings in the recorded Node runtime. We make no detector-score or statistical-watermark removal claim.

Before and after observations; full code points and strings are in the JSON download.
Fixture and modeInput string and code pointsOutput and cleaner statusObserved before / after
Marked parent
direct string / keep / invisible true
"safe/..​/private.txt"
U+0073 U+0061 U+0066 U+0065 U+002F U+002E U+002E U+200B U+002F U+0070 U+0072 U+0069 U+0076 U+0061 U+0074 U+0065 U+002E U+0074 U+00 …
"safe/../private.txt"
Removed 1 invisible character
{"normalized":"safe/..​/private.txt","joined":"/workspace/safe/..​/private.txt"}
{"normalized":"private.txt","joined":"/workspace/private.txt"}
Plain parent
direct string / keep / invisible true
"safe/../private.txt"
U+0073 U+0061 U+0066 U+0065 U+002F U+002E U+002E U+002F U+0070 U+0072 U+0069 U+0076 U+0061 U+0074 U+0065 U+002E U+0074 U+0078 U+00 …
"safe/../private.txt"
No selected invisible characters found
{"normalized":"private.txt","joined":"/workspace/private.txt"}
{"normalized":"private.txt","joined":"/workspace/private.txt"}
Ordinary directory
direct string / keep / invisible true
"safe/docs/private.txt"
U+0073 U+0061 U+0066 U+0065 U+002F U+0064 U+006F U+0063 U+0073 U+002F U+0070 U+0072 U+0069 U+0076 U+0061 U+0074 U+0065 U+002E U+00 …
"safe/docs/private.txt"
No selected invisible characters found
{"normalized":"safe/docs/private.txt","joined":"/workspace/safe/docs/private.txt"}
{"normalized":"safe/docs/private.txt","joined":"/workspace/safe/docs/private.txt"}
Retained joiner
direct string / keep / invisible true
"safe/..‍/private.txt"
U+0073 U+0061 U+0066 U+0065 U+002F U+002E U+002E U+200D U+002F U+0070 U+0072 U+0069 U+0076 U+0061 U+0074 U+0065 U+002E U+0074 U+00 …
"safe/..‍/private.txt"
No selected invisible characters found
{"normalized":"safe/..‍/private.txt","joined":"/workspace/safe/..‍/private.txt"}
{"normalized":"safe/..‍/private.txt","joined":"/workspace/safe/..‍/private.txt"}

A directory label becomes lexical navigation

Our first fixture places U+200B after two dots, so the segment is not exactly the parent notation. The original normalized string retains safe and that marked segment. Cleaning joins the two dots directly to the following slash; normalization then removes safe and returns private.txt. Joining against the fixed /workspace base similarly changes from a path under safe to /workspace/private.txt. The ordinary parent reference already produces that shorter result, while the docs reference preserves its directory chain. The retained U+200D row stays a named segment. The table records both operations to show the same deletion at two explicit lexical stages.

Lexical paths do not establish physical containment

The observer uses path.posix even on this Windows host. It never calls realpath, opens a file, follows a symlink or contacts a server. Our URL parent-segment guide concerns URL construction and percent encoding; filesystem normalization here operates directly on path spelling. Neither result establishes access to a protected resource. The chosen base and filenames are invented fixture labels. The cleaner has no path-aware policy, and its successful removal message does not prove that the edited path still names an intended directory. Node documents normalization rules, but physical resource resolution requires the actual destination filesystem and application context.

Recheck the directory relationship after editing

Preserve the original spelling and the intended base directory. Run the destination path logic on both strings and inspect the complete normalized result, including which directory components disappeared. If an application requires containment, enforce that requirement in its own filesystem-aware validation rather than using cleanup as an authorization check. Do not treat a parent notation as ordinary filename punctuation once an edit activates it. These four synthetic cases establish a repeatable lexical change and unchanged controls; they cannot verify a sandbox, a symlink target, a Windows path or permission to read any private file.

Reproduce this test

Save reproduce.cjs and tested-app.js in the same folder. Run the command below with Node.js. The harness prints its runtime, script SHA-256 and every measured row. Compare those rows with the original record. Using a newer script or runtime creates a new experiment; retain the version information with your rerun.

node reproduce.cjs

Reference and next check

Node.js path API provides the relevant primary definition. The table and fixture analysis are original measurements. For broader inspection, use our Unicode inspector. Read the scope distinction before interpreting cleanup as a watermark result.