CLAUDE WATERMARK REMOVER · PRACTICAL TEST
Why does editing one filled row change a second cleaned-text row?
Array(2).fill with one object stores the same object twice in our fixture. Editing its first row changes both views. Array.from with an object-producing callback creates separate rows, so only the edited row changes.
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 value direct string / keep / invisible true | "AB"U+0041 U+200B U+0042 | "AB"Removed 1 invisible character | {"sharedSame":true,"separateSame":false,"shared":["AB!","AB!"],"separate":["AB!","AB"]}{"sharedSame":true,"separateSame":false,"shared":["AB!","AB!"],"separate":["AB!","AB"]} |
| Plain value direct string / keep / invisible true | "AB"U+0041 U+0042 | "AB"No selected invisible characters found | {"sharedSame":true,"separateSame":false,"shared":["AB!","AB!"],"separate":["AB!","AB"]}{"sharedSame":true,"separateSame":false,"shared":["AB!","AB!"],"separate":["AB!","AB"]} |
| Empty value direct string / keep / invisible true | "" | ""No selected invisible characters found | {"sharedSame":true,"separateSame":false,"shared":["!","!"],"separate":["!",""]}{"sharedSame":true,"separateSame":false,"shared":["!","!"],"separate":["!",""]} |
| Retained joiner direct string / keep / invisible true | "AB"U+0041 U+200D U+0042 | "AB"No selected invisible characters found | {"sharedSame":true,"separateSame":false,"shared":["AB!","AB!"],"separate":["AB!","AB"]}{"sharedSame":true,"separateSame":false,"shared":["AB!","AB!"],"separate":["AB!","AB"]} |
Two positions can refer to one mutable object
The observer creates a two-row array using fill with a single object whose text is the supplied string. It then appends an exclamation mark through row zero. Both rows display the appended character, and sharedSame records true. The comparison array calls an object-producing function separately for each position. Its identity check is false, and after the same first-row edit only its first string gains the punctuation. The observer deliberately performs both edits; the second changed display is not an additional operation by the cleaner.
The empty control reveals the same aliasing
The empty-value control produces two exclamation marks in the shared view and an exclamation mark followed by empty text in the separate view. Plain AB reproduces the first fixture after marker deletion. The retained U+200D control keeps that joiner in all text values. These controls show that reference sharing exists regardless of which characters the homepage removes. Identity booleans are saved beside visible rows because equal-looking strings alone cannot prove that their containing objects are independent. Two separately created objects can initially hold exactly the same primitive string.
Allocate at the level where independent edits happen
If each row should accept later edits independently, construct a fresh row object for each position. That is the explicit policy demonstrated by the factory comparison. The example has only one primitive text field, so it does not promise independence of nested objects returned by a more complex factory. A callback that itself reuses a shared child can still create aliases. The experiment does not implement deep cloning, persistence, reactive state or undo. It isolates fill repeating one object reference and contrasts it with two independently allocated plain objects.
Reference sharing is downstream from cleanup
The homepage callback receives one string and produces one string before either row collection is created. It does not populate or mutate the arrays. Earlier Buffer experiments involve shared byte storage, while this experiment involves the same JavaScript object in two positions; the recorded mechanisms are distinct. Every row is a local diagnostic object, not an uploaded spreadsheet or conversation. Reproducing the shared edit says nothing about Claude provenance, statistical marking or AI classification. Retain the construction code when diagnosing apparently linked row changes.
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
ECMAScript Array.prototype.fill 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.