Zerowidth CleanerAll measured guides

CLAUDE WATERMARK REMOVER · PRACTICAL TEST

Why does a cleaned zero still display a minus sign?

Our cleaned -0 becomes a Number that is negative zero. Intl.NumberFormat with signDisplay auto prints -0; negative and exceptZero print 0 in these fixtures. A display policy can hide the sign without changing the stored numeric value.

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

Open the Claude text cleaner · Full measured data

Code-point comparison for Marked negative zero

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 negative zero
direct string / keep / invisible true
"-​0"
U+002D U+200B U+0030
"-0"
Removed 1 invisible character
{"number":"NaN","isNegativeZero":false,"auto":"NaN","negative":"NaN","exceptZero":"NaN"}
{"number":"0","isNegativeZero":true,"auto":"-0","negative":"0","exceptZero":"0"}
Negative zero
direct string / keep / invisible true
"-0"
U+002D U+0030
"-0"
No selected invisible characters found
{"number":"0","isNegativeZero":true,"auto":"-0","negative":"0","exceptZero":"0"}
{"number":"0","isNegativeZero":true,"auto":"-0","negative":"0","exceptZero":"0"}
Positive zero
direct string / keep / invisible true
"0"
U+0030
"0"
No selected invisible characters found
{"number":"0","isNegativeZero":false,"auto":"0","negative":"0","exceptZero":"0"}
{"number":"0","isNegativeZero":false,"auto":"0","negative":"0","exceptZero":"0"}
Negative one
direct string / keep / invisible true
"-1"
U+002D U+0031
"-1"
No selected invisible characters found
{"number":"-1","isNegativeZero":false,"auto":"-1","negative":"-1","exceptZero":"-1"}
{"number":"-1","isNegativeZero":false,"auto":"-1","negative":"-1","exceptZero":"-1"}

The ordinary string form hides a numeric distinction

The marked input places U+200B between the minus and zero, so Number initially yields NaN. After deletion, the observer records String(number) as 0 while Object.is(number, -0) is true. The auto formatter returns -0. The negative and exceptZero formatters both return 0. Those fields show why printing a Number with its ordinary string conversion is not enough to explain a later signed display. Each formatter receives the same numeric value in the same call; the difference is the selected signDisplay option rather than additional cleanup or a second conversion.

Positive zero and negative one bound the policy

The unmarked -0 reference yields the same sign disagreement without any selected character. Positive zero yields 0 through all three formatters and reports false for negative-zero identity. Negative one yields -1 through all three and is not negative zero. The controls establish that the tested negative option suppresses the sign of negative zero without suppressing an ordinary negative number in this matrix. We keep NaN outputs from the marked pre-cleanup branch too, rather than treating them as valid zero. All formatters use the fixed en-US locale and their complete option objects are preserved in the harness.

Choose presentation without silently changing the value

If the product intends zero to display without a minus, select and test that presentation policy at the formatting stage. Preserve the underlying value if its sign is meaningful to later calculations. Conversely, when the sign matters, do not infer its absence from a generic string display. This test calls no rounding operation before formatting and does not mutate the stored Number. The homepage only edits the supplied text. A no-findings message for an ordinary -0 string would therefore be consistent with a destination formatter continuing to show its sign.

Formatting is separate from serialization

The existing negative-zero guide measures what happens when JSON serialization collapses the sign. Here no JSON round trip is used to produce the numeric value given to the formatters. JSON is only the container for named observations, including an explicit boolean that preserves the diagnostic distinction. We test two zero signs, one negative integer and a marked spelling in the recorded runtime. We do not cover every locale, rounded small quantity or unsupported browser. These synthetic measurements say nothing about the source author, Claude provenance, AI classification or removal of a statistical watermark.

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

ECMA-402 InitializeNumberFormat 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.