CLAUDE WATERMARK REMOVER · PRACTICAL TEST
Why do commas and spaces appear after formatting cleaned list items?
Our English Intl.ListFormat adds literal separators after cleanup. formatToParts distinguishes them from the supplied item strings; an embedded comma stays inside an element, and an empty item still affects the formatted list.
Open the Claude text cleaner · Full measured data
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.
| Fixture and mode | Input string and code points | Output and cleaner status | Observed before / after |
|---|---|---|---|
| Marked first item direct string / keep / invisible true | "AB"U+0041 U+200B U+0042 | "AB"Removed 1 invisible character | {"items":["AB","C","D"],"formatted":"AB, C, and D","parts":[{"type":"element","value":"AB"},{"type":"literal","value":", "},{"type":"element","value":"C"},{"type":"literal","value":", and "},{"type":"element","value":"D"}]}{"items":["AB","C","D"],"formatted":"AB, C, and D","parts":[{"type":"element","value":"AB"},{"type":"literal","value":", "},{"type":"element","value":"C"},{"type":"literal","value":", and "},{"type":"element","value":"D"}]} |
| Plain first item direct string / keep / invisible true | "AB"U+0041 U+0042 | "AB"No selected invisible characters found | {"items":["AB","C","D"],"formatted":"AB, C, and D","parts":[{"type":"element","value":"AB"},{"type":"literal","value":", "},{"type":"element","value":"C"},{"type":"literal","value":", and "},{"type":"element","value":"D"}]}{"items":["AB","C","D"],"formatted":"AB, C, and D","parts":[{"type":"element","value":"AB"},{"type":"literal","value":", "},{"type":"element","value":"C"},{"type":"literal","value":", and "},{"type":"element","value":"D"}]} |
| Embedded comma direct string / keep / invisible true | "A,B"U+0041 U+002C U+0042 | "A,B"No selected invisible characters found | {"items":["A,B","C","D"],"formatted":"A,B, C, and D","parts":[{"type":"element","value":"A,B"},{"type":"literal","value":", "},{"type":"element","value":"C"},{"type":"literal","value":", and "},{"type":"element","value":"D"}]}{"items":["A,B","C","D"],"formatted":"A,B, C, and D","parts":[{"type":"element","value":"A,B"},{"type":"literal","value":", "},{"type":"element","value":"C"},{"type":"literal","value":", and "},{"type":"element","value":"D"}]} |
| Empty first item direct string / keep / invisible true | "" | ""No selected invisible characters found | {"items":["","C","D"],"formatted":", C, and D","parts":[{"type":"literal","value":", "},{"type":"element","value":"C"},{"type":"literal","value":", and "},{"type":"element","value":"D"}]}{"items":["","C","D"],"formatted":", C, and D","parts":[{"type":"literal","value":", "},{"type":"element","value":"C"},{"type":"literal","value":", and "},{"type":"element","value":"D"}]} |
Parts identify which characters the formatter introduced
We format a three-item list containing the tested first item followed by C and D. The marked first item loses U+200B when cleaned, but both formatted versions contain the formatter’s comma-space and comma-and separators. formatToParts labels those spans literal and the supplied item strings element. The embedded-comma control keeps A,B together in one element, although its display contains a comma similar to the separator. The empty-string control produces a leading literal comma-space in this runtime and does not produce an empty element part. The table includes the source items, complete formatted string and every part, exposing which stage produced each visible span.
A presentation list does not supply a CSV serialization
The destination is Intl.ListFormat with English, long style and conjunction type. It formats an authored array and does not parse CSV or encode a reversible data record. Our quoted CSV guide studies field grammar; this page studies generated presentation punctuation and its labeled provenance. The homepage processes only the first item and never sees the complete formatted output until a user separately supplies it. The formatter does not infer whether an empty first item should be filtered. We do not test other locales, styles, conjunction policies, list lengths or every runtime’s locale data. The recorded ICU version matters if a future rerun changes wording or separators.
Keep elements separate from display literals
If punctuation appears after cleaning, inspect the destination’s formatting stage before concluding the cleanup failed. Retain the original item array and use the formatter’s parts when the application needs to distinguish item content from generated separators. Decide deliberately whether empty items belong in the source list; removing them changes the formatter’s input contract. Do not split the formatted string on commas to recover data: the embedded-comma fixture makes that ambiguity directly observable. Our downloads show one exact locale policy and four first-item cases, with every span labeled. They do not implement a list parser or guarantee a formatted list can be reversed. Validate storage and display independently when a later operation generates new characters.
Read the empty-item control without inventing a removal
The empty first item is authored as an empty string from the start. Its cleaner status has no selected invisible characters, and the formatter still receives three array positions. The resulting leading separator therefore cannot be attributed to a removed marker or an item automatically dropped by cleanup. Its parts array lacks an empty element span while retaining a literal separator. Compare the source array and parts together: counting element spans alone would miss that the input still has three positions. This observation is limited to this recorded English formatter and should be rerun for another locale or runtime. A deliberate filtering rule would be a separate experiment with a different source array.
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.cjsReference and next check
ECMA-402 Intl.ListFormat 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.