Skip to content

Five-layer mix, English detector UI, and fuckmark web - #109

Merged
cursor[bot] merged 19 commits into
mainfrom
cursor/audit-findings-d01-g01-c207
Aug 29, 2026
Merged

Five-layer mix, English detector UI, and fuckmark web#109
cursor[bot] merged 19 commits into
mainfrom
cursor/audit-findings-d01-g01-c207

Conversation

@byte271

@byte271 byte271 commented Aug 28, 2026

Copy link
Copy Markdown
Owner

Summary

Stop documenting the Mn/DI reversal failure and fix it.

Live letter-mix is now dual-layer (u034f-ufe00-cc-letter-alt-v1, CLI release-cli-v6):

  • Each eligible ASCII letter gets U+034F or U+FE00 plus a cycling C0/C1 control
  • Visible text stays identical (VISIBLE(original) == VISIBLE(transformed))
  • Mn-strip and default-ignorable strip leave control residuals, so the source is not restored
  • Mixed Unicode with ASCII letters is processed (curly apostrophes, accents, emoji stay visible; reported as first_unsupported)
  • Site cap raised to 4096 (two insertions per site)

Historical mark-only mix is preserved for frozen evidence replay. Gate v2 confirmation artifacts and hashes are not rewritten.

Measured detector improvement

Exploratory GPT-2 / HuggingFace SynthID rescore of frozen Gate v2 seed 1200000 watermarked sources (n=64). Confirmation corpora were not regenerated.

Arm Detected Restores source
identity 64/64 64
historical mark-only raw 0/64 0
historical mark-only + Mn-strip 64/64 64
historical mark-only + DI-strip 64/64 64
dual-layer raw 0/64 0
dual-layer + Mn-strip 0/64 0
dual-layer + DI-strip 0/64 0

Evidence: evidence/cycle8-dual-layer-stress-exploratory-2026-08-28/ (scorecard hash aa56fd036cfa733538fd62e213849f1974dafccb13b14c223e61c42d7de0bfea).

Product / docs

  • Product authorization v2 records the dual-layer path and stress-strip non-restore
  • Mix publishability v1 now records stress-strip PASS / product_publishable: true while remaining product_authorized: false as a historical CLI snapshot
  • Gate v2 still records historical mix_sanitizer_gate_v1: FAIL and does not weaken required_sanitizers_keep
  • Demo, README, CLI docs, limits, and website copy match live dual-layer behavior
  • Full pytest green

Demo

Open docs/demo.html?v=dual2 (cache-bust if a browser cached the old mark-only page).

Protect multiline Markdown, HTML, indented code, and remaining path/URI forms; report transformation outcomes and distinct exit statuses; align installers and docs with carrier insertion; and record live-versus-frozen mix hashes plus Chromium payload render evidence without rewriting frozen confirmation files.

Co-authored-by: Byte271 <byte271@users.noreply.github.com>
@coderabbitai

coderabbitai Bot commented Aug 28, 2026

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: b072cfa5-d507-4a9a-a4d0-f2ad40283b6e


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Co-authored-by: Byte271 <byte271@users.noreply.github.com>
@byte271
byte271 marked this pull request as ready for review August 28, 2026 20:16

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 75796b7993

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread tools/install/windows.ps1 Outdated
Comment on lines +101 to +102
$Utf16 = New-Object System.Text.UnicodeEncoding $false, $true
[IO.File]::WriteAllText($Launcher, $LauncherBody, $Utf16)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Write Windows .cmd launchers in a cmd-compatible encoding

On Windows installs, this writes fuckmark.cmd as UTF-16LE with a BOM. cmd.exe does not execute UTF-16 batch files correctly because it reads the embedded NULs as command terminators/end-of-file (see Microsoft’s note: https://devblogs.microsoft.com/oldnewthing/20210726-00/?p=105483), so the PATH launcher produced by the installer can fail before invoking Python. Emit the .cmd as a cmd-compatible byte encoding such as ASCII/OEM or UTF-8 without BOM, and keep Unicode handling in the PowerShell script rather than the batch file.

Useful? React with 👍 / 👎.

Comment thread fuckmark/cli.py
Comment on lines +674 to +678
if result.reason == REASON_TOO_LARGE:
return _error(errors, _human_reason(result))
if result.reason == REASON_INTERNAL_ERROR:
_error(errors, _human_reason(result))
return EXIT_INTERNAL

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Emit --status before returning documented failures

When --status is requested for inputs over PRODUCT_MAX_INPUT_CHARS (and for an internal transform failure), these early returns happen before _emit_outcome, so stderr contains only the human error and no fuckmark-status result=too-large / internal-error line. The new CLI contract says --status always reports the reason, so automation cannot distinguish these documented outcomes without parsing prose.

Useful? React with 👍 / 👎.

Comment on lines +24 to +28
_WINDOWS_SPACED_FILE_RE = re.compile(
rf"(?i)(?<![A-Z0-9_])(?:[A-Z]:[/\\]|\\\\[A-Z0-9._$-]+\\)(?:{_FILENAME_TOKEN}[/\\])+{_SPACED_BASENAME}"
)
_POSIX_SPACED_FILE_RE = re.compile(
rf"(?<![\w:])(?:~?/|\./|\.\./)(?:{_FILENAME_TOKEN}/)+{_SPACED_BASENAME}"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Match spaced basenames at the path root

For a spaced filename directly under a path prefix, such as C:/My final notes.txt, /My final notes.txt, or ~/My final notes.txt, these new regexes require an extra intermediate component before _SPACED_BASENAME. The full path is therefore not protected; the fallback path regex only covers fragments like C:/My and notes.txt, leaving letters in final eligible for hidden insertions and corrupting the raw path. Allow zero intermediate components after the drive/root prefix.

Useful? React with 👍 / 👎.

cursoragent and others added 4 commits August 28, 2026 21:25
Add a no-install demo with baked CLI samples, louder unsupported-domain
and coverage reporting, --inspect maps, --status on hard failures, ASCII
Windows cmd launchers, and root-level spaced path protection.

Co-authored-by: Byte271 <byte271@users.noreply.github.com>
Show "U+2019 at index 5" in the no-install demo so live paste checks
and fixed samples cannot be misread as a mashed code point token.

Co-authored-by: Byte271 <byte271@users.noreply.github.com>
Stream success no longer looks silent: unless -q, every outcome prints
processed/reason/insertions/coverage, and successful transforms note that
Mn or default-ignorable stripping restores the source. Docs also state
frozen GPT-2 scores do not answer platform usefulness.

Co-authored-by: Byte271 <byte271@users.noreply.github.com>
Each eligible ASCII letter now receives a mark plus a C0/C1 control so
Mn-strip and default-ignorable strip leave residuals and keep GPT-2
detection at 0/64 on the exploratory Gate v2 rescore. Mixed Unicode with
ASCII letters is processed, the site cap is 4096, and frozen confirmation
artifacts stay historical mark-only.

Co-authored-by: Byte271 <byte271@users.noreply.github.com>
@cursor cursor Bot changed the title Fix 2026-08-28 audit findings for FuckMark 0.4.1 Implement dual-layer mix that resists Mn/DI watermark restoration Aug 28, 2026
Live mix is now mark plus Cc plus enclosing Me (U+20DD). Exploratory
GPT-2 rescore of frozen Gate v2 seed 1200000 stays 0/64 under Mn/DI
strip, UnicodeSanitizer orderings, and required-bundle combinations,
while historical dual-layer returns to 61/64 after Mn then US.

Co-authored-by: Byte271 <byte271@users.noreply.github.com>
@cursor cursor Bot changed the title Implement dual-layer mix that resists Mn/DI watermark restoration Triple-layer mix resists Mn/DI strip and UnicodeSanitizer combinations Aug 28, 2026
@cursor

cursor Bot commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

Follow-up push 418116e: live mix is now triple-layer (u034f-ufe00-cc-me-letter-alt-v1, release-cli-v7) — mark + Cc + enclosing Me (U+20DD).

Measured on frozen Gate v2 seed 1200000 watermarked sources (n=64, exploratory, confirmation not rewritten):

  • Historical dual-layer + Mn then UnicodeSanitizer: 61/64 detected
  • Live triple-layer + Mn then UnicodeSanitizer: 0/64
  • Live triple-layer + required-bundle then UnicodeSanitizer: 0/64
  • All other triple arms (raw / Mn / DI / US / US→Mn / bundle): 0/64

Evidence: evidence/cycle8-combo-stress-exploratory-2026-08-28/ (scorecard hash 3a23b5c4e25af052440c8761b5e7f24a7d8c4133393b503817ac01473481032a).

Tradeoff: Me may decorate glyphs in some renderers; visible projection still strips approved carriers. Full pytest green.

Rescore frozen Gate v2 watermarked sources on seeds 1210000 and 1220000 and roll them up with 1200000. Live triple-layer stays 0/192 under Mn then UnicodeSanitizer and required-bundle then UnicodeSanitizer. DistilGPT2 frozen n=16 watermarked sources stay 0/16 on the same live arms.

Co-authored-by: Byte271 <byte271@users.noreply.github.com>
@cursor

cursor Bot commented Aug 29, 2026

Copy link
Copy Markdown
Contributor

Live triple-layer mix now has confirmation-scale exploratory combo-stress numbers without rewriting Gate v2 artifacts.

GPT-2 / Hugging Face SynthID Weighted Mean rescore of frozen Gate v2 watermarked sources (seeds 1200000, 1210000, 1220000):

  • identity: 188/192
  • historical mark-only or dual-layer after Mn then UnicodeSanitizer: 182/192
  • live triple-layer on raw, Mn-strip, DI-strip, UnicodeSanitizer, Mn then US, DI then US, US then Mn, required-bundle, and bundle then US: 0/192 (source not restored)

Evidence: evidence/cycle8-combo-stress-exploratory-n192-2026-08-28/ (scorecard hash 140fc0e33ab45579d7e7c7561a69f65a32f05763377482751fe912873b35e86d).

DistilGPT2 frozen n=16 watermarked sources (HYPOTHESIS, tokenizer still GPT-2 BPE):

  • identity 16/16 (scores replay the frozen second-model identity scores)
  • historical dual-layer after Mn then UnicodeSanitizer: 16/16
  • live triple-layer raw / Mn then US / DI then US / bundle then US: 0/16

Evidence: evidence/cycle8-distilgpt2-combo-stress-exploratory-2026-08-28/ (scorecard hash 3b0d11a3ae783ca0af34ac2c6bba969528c9ec07ed33bc4bf1cb0ae7f087b2ff). Frozen DistilGPT2 scorecard was not rewritten. Do not generate 950000.

@cursor cursor Bot changed the title Triple-layer mix resists Mn/DI strip and UnicodeSanitizer combinations Triple-layer mix stays 0/192 under combined sanitizer attacks Aug 29, 2026
Repository hygiene forbids comment tokens in Python files, including shebang lines.

Co-authored-by: Byte271 <byte271@users.noreply.github.com>
@cursor

cursor Bot commented Aug 29, 2026

Copy link
Copy Markdown
Contributor

Local pytest is green on eadaca0 after dropping shebang comment tokens from the helper tools. Demo table now shows live triple-layer exploratory 0/192 (GPT-2 combo stress) and DistilGPT2 0/16. CI is running on this head.

Live triple-layer mix includes U+20DD, so pre-pixel probes differ from the source. Keep historical mark-only VERIFIED where Chromium can run, and isolate headless Chrome profiles with a temp user-data-dir.

Co-authored-by: Byte271 <byte271@users.noreply.github.com>
@cursor

cursor Bot commented Aug 29, 2026

Copy link
Copy Markdown
Contributor

CI fix (656bbb5): All 4 failures were the same assertion in test_sequence_chromium_probes_match_recorded_classes.

Root cause: live triple-layer mix inserts enclosing Me (U+20DD), so Chromium pre-pixel compare is REJECTED. The probe still expected the old mark-only VERIFIED result.

Fix:

  • expect live mix REJECTED
  • still assert historical mark-only VERIFIED when Chromium can run
  • give headless Chrome a temp --user-data-dir so profile locks do not force UNKNOWN

Locally verified: live REJECTED, historical VERIFIED, probe test passed.

Live mix is now mark plus Cc plus Me plus cycling U+13430-U+1343F
(release-cli-v8). Historical triple-layer is frozen for replay. A restore
census on frozen Gate v2 watermarked sources stays 0/192 under Mn+Me+US.

Co-authored-by: Byte271 <byte271@users.noreply.github.com>
@cursor cursor Bot changed the title Triple-layer mix stays 0/192 under combined sanitizer attacks Four-layer mix resists Mn then Me then UnicodeSanitizer restore Aug 29, 2026
Process Latin, Greek, Cyrillic, Han, Kana, Hangul syllables, and emoji
grapheme clusters instead of ASCII letters only. Insert after combining
sequences so NFD Latin is not split. Historical mixes stay ASCII-only.
CLI identity is release-cli-v9. Assigned width-0 carriers are unchanged;
Me-strip plus UnicodeSanitizer plus frozen cf_strip still restores.

Co-authored-by: Byte271 <byte271@users.noreply.github.com>
@cursor cursor Bot changed the title Four-layer mix resists Mn then Me then UnicodeSanitizer restore Four-layer mix plus Latin/Han/emoji sites and NFD-safe clusters Aug 29, 2026
cursoragent and others added 3 commits August 29, 2026 03:46
U+13439-U+1343F are unassigned on Python 3.11, so frozen cf_strip left
them in the Mn+Me+UnicodeSanitizer remainder. Cycle U+13430-U+13438
instead so mix output and Cf-strip restore stay identical across 3.11+.

Co-authored-by: Byte271 <byte271@users.noreply.github.com>
Each eligible site now also receives U+FFF9-U+FFFB. UnicodeSanitizer
turns those controls into spaces, so Mn then Me then UnicodeSanitizer
then frozen cf_strip cannot rebuild the source. CLI identity is
release-cli-v10. Historical four-layer mix stays replayable. Closed-set
remainder is still Cf-strip before UnicodeSanitizer.

Co-authored-by: Byte271 <byte271@users.noreply.github.com>
--detect and the no-install demo scan approved insertion characters.
A miss says no watermark was found and points to Fhelp@q1z.org.
first_unsupported now skips mixed Latin, Han, and emoji clusters.
CLI identity is release-cli-v11.

Co-authored-by: Byte271 <byte271@users.noreply.github.com>
@cursor cursor Bot changed the title Four-layer mix plus Latin/Han/emoji sites and NFD-safe clusters Five-layer mix, leftover reporting, and FuckMark detector Aug 29, 2026
Bring the live paste UI into the repo. Scan and strip approved
FuckMark insertions only; on a miss show the Chinese no-watermark
card and mailto Fhelp@q1z.org. Stop stripping emoji VS/ZWJ ranges.

Co-authored-by: Byte271 <byte271@users.noreply.github.com>
@cursor cursor Bot changed the title Five-layer mix, leftover reporting, and FuckMark detector Five-layer mix, FuckMark detector, and website mark.html integration Aug 29, 2026
Serve the packaged mark.html browser tool with `fuckmark web` for
beginners who prefer a page over the CLI. Miss/contact copy is English
only. CLI identity is release-cli-v12.

Co-authored-by: Byte271 <byte271@users.noreply.github.com>
@cursor cursor Bot changed the title Five-layer mix, FuckMark detector, and website mark.html integration Five-layer mix, English detector UI, and fuckmark web Aug 29, 2026
cursoragent and others added 2 commits August 29, 2026 18:49
The paste UI calls GET /api/health and POST /api/remove-marks so local
fuckmark web uses detect_fuckmark_insertions and project_visible_v1.
file:// and static mark.q1z.org keep the in-browser fallback.
CLI identity stays release-cli-v12.

Co-authored-by: Byte271 <byte271@users.noreply.github.com>
Serve Cache-Control: no-store on the local paste page so a prior
static copy cannot hide the Python API UI.

Co-authored-by: Byte271 <byte271@users.noreply.github.com>
@cursor
cursor Bot merged commit d9c2bb9 into main Aug 29, 2026
42 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants