Claude Sonnet 5.5 (effort default (no --effort flag) · thinking on) on Unicode-correct username canonicalisation (NFKC, casefold, mixed-script), terminal width, cluster-safe truncation and slugs
AClaude Sonnet 5.5default · thinking on · Claude Code 2.1.299 (headless -p) · cloud · 2026-10-17 · by @bobsiopener
- Estimated cost
- $0.09
- Wall time
- 33s
- Human step-ins
- 0
- Outcome
- Pass
Compare with other models on this task →
Summary
Exact prompt
# Task: make the text helpers Unicode-correct Rewrite the four functions in `textnorm.py` (Python stdlib only, `unicodedata` is fine) to these rules: **canonical_username(s)** - used to detect duplicate/impersonating accounts. 1. Remove zero-width/format characters U+200B, U+200C, U+200D, U+2060, U+FEFF and U+00AD (soft hyphen); apply NFKC; casefold (Python `str.casefold()`; note it maps a Greek final sigma ς to σ, so `"Δημήτρης"` -> `"δημήτρησ"`); strip surrounding whitespace. 2. The result must be 3-32 characters, contain only letters (any script, category L*), digits (Nd), `.`, `_`, `-`, and must not mix scripts: all letters must come from one script among Latin, Greek, Cyrillic (judge by `unicodedata.name` starting with `LATIN`, `GREEK`, `CYRILLIC`; letters from any other script are allowed only if all letters are from that same other script, judged by the first word of the name). Otherwise raise `ValueError`. Examples: `" John_Doe "` -> `"john_doe"`; `"STRASSE"` and `"straße"` both -> `"strasse"`; `"pаypal"` (Cyrillic а) -> ValueError. **display_width(s)** - terminal columns: characters with East Asian Width `W` or `F` count 2; combining marks (categories Mn, Me), format chars (Cf) and the zero-width chars above count 0; control characters (Cc) count 0; everything else 1 (so East Asian Width `A`/`N`/`Na`/`H` count 1: `…` is 1, `❤` is 1, each regional-indicator letter is 1 so a flag pair is 2, and U+FE0F is 0 as a combining mark). **truncate(s, width, ellipsis="…")** - if `display_width(s) <= width` return `s` unchanged. Otherwise return the longest prefix such that display_width(prefix) + display_width(ellipsis) <= `width`, never splitting a base character from its following combining marks/ZWJ/variation selectors (U+FE00-FE0F), never splitting a regional-indicator pair (flag) and never leaving a dangling ZWJ (U+200D) at the end of the prefix. Then append ellipsis. If even the ellipsis doesn't fit, return "". **slugify(s)** - NFKD, drop combining marks, map `ß`->`ss`, `æ`->`ae`, `œ`->`oe`, `ø`->`o`, `ł`->`l`, `đ`->`d`, `þ`->`th` (and their uppercase forms), lowercase, then every run of characters other than `a-z0-9` becomes a single `-`; strip leading/trailing `-`. If longer than 60 characters, cut to 60 and then, if the cut fell inside a word (the 60th and 61st characters are both letters/digits), back off to the last `-` within the 60 (when there is one); finally strip trailing `-`. Examples: 20 x "word " -> 12 x "word" joined by `-`; `"abc " + 70 x "y"` -> `"abc"`; 70 x "x" -> 60 x "x". Empty result -> `"n-a"`. No network.
Tests hit casefold (ß->ss, final sigma), NFKC compatibility chars (fullwidth, ligatures, roman numerals), homoglyph mixed-script detection, East Asian width, combining marks, flags, ZWJ emoji and variation selectors in truncation, and transliteration + word-boundary cuts in slugs. Original benchmark task written for usecaserank.com (not based on a specific public post). Headless, offline run on a reproducible fixture. Each run's notes say how its cost was measured (estimates are marked).
Success criteria: 1. All 8 hidden unittest cases pass: username normalisation, script rules, invalid usernames, display width, basic truncation, grapheme-safe truncation, slug transliteration, slug length cutting.
Setup notes: Use Case Scout batch 6 case f07-unicode-text-normalization (offline fixture). Prepared with batch6/prepare.sh; hidden key/tests kept outside the agent's work dir. Prompt = TASK.md verbatim. Scored with the scout's scorer: `python score.py WORKDIR KEYDIR`. Tools: Read/Write/Edit/Glob/Grep/Bash, web disabled. Single run, no retries. Claude Code's own reported cost for claude-sonnet-5.5: $0.093315. Score: 8/8. Cost is an ESTIMATE: measured tokens x pricing.json list price (Claude Pro subscription, nothing billed); input_tokens include cache reads and writes. Single run.
Estimated cost List-price estimate; not actually billed.
Metrics
- Estimated cost
- $0.09
- Wall time
- 33s
- Human step-ins
- 0
- Turns
- 4
| Model | Input tok | Output tok | Cost |
|---|---|---|---|
| AClaude Sonnet 5.5anthropic/claude-sonnet-5.5effort default (no --effort flag) · thinking on | 83,989 | 4,369 | $0.09 |
Reproduce this run
- Use the use case prompt on the use case page.
- Same setup: Claude Sonnet 5.5 (anthropic/claude-sonnet-5.5, effort default (no --effort flag) · thinking on) via
Claude Code 2.1.299 (headless -p), cloud. - It counts as a success only if it meets every success criterion: 1. All 8 hidden unittest cases pass: username normalisation, script rules, invalid usernames, display width, basic truncation, grapheme-safe truncation, slug transliteration, slug length cutting.
- Log model, tokens, wall time, human step-ins and the evidence log, then submit it as a reproduction. A different model? Submit a head-to-head rerun.
How runs are scored: Methodology.
Was this useful?
Automated checks
Trust 80% comes from these checks (how Trust % works).
- Run date is not in the future : passed
- Model is in the dated pricing table : passed
- Cost recomputed from tokens matches : passed
- Cached tokens are consistent : passed
- Output throughput is plausible : passed
- Autonomy matches step-ins : passed
- Step-ins do not exceed turns : passed
- Retries agree with first-try result : passed
- Evidence log SHA-256 matches : passed
- Evidence log is substantial : passed
Evidence log
[
{
"duration_api_ms": 32437,
"stop_reason": "end_turn",
"session_id": "[REDACTED]",
"total_cost_usd": 0.0933154,
"usage": {
"input_tokens": 8,
"cache_creation_input_tokens": 10567,
"cache_read_input_tokens": 73414,
"output_tokens": 4369,
"output_tokens_details": {
"thinking_tokens": 1648
},
"server_tool_use": {
"web_search_requests": 0,
"web_fetch_requests": 0
},
"service_tier": "standard",
"cache_creation": {
"ephemeral_1h_input_tokens": 10567,
"ephemeral_5m_input_tokens": 0
},
"inference_geo": "global",
"iterations": [
{
"input_tokens": 2,
"output_tokens": 669,
"cache_read_input_tokens": 22623,
"cache_creation_input_tokens": 483,
"cache_creation": {
"ephemeral_5m_input_tokens": 0,
"ephemeral_1h_input_tokens": 483
},
"type": "message"
}
],
"speed": "standard",
"fallback_credit": null
},
"modelUsage": {
"claude-sonnet-5-5": {
"inputTokens": 8,
"outputTokens": 4369,
"cacheReadInputTokens": 73414,
"cacheCreationInputTokens": 10567,
"webSearchRequests": 0,
"costUSD": 0.0933154,
"contextWindow": 1000000,
"maxOutputTokens": 128000,
"thinkingTokens": 1648,
"canonicalModel": "claude-sonnet-5-5",
"provider": "firstParty",
"costBasis": "list"
}
},
"permission_denials": [],
"terminal_reason": "completed",
"fast_mode_state": "off",
"fast_mode_disabled_reason": "sdk_opt_in_required",
"subagent_stats": {
"spawned": 0,
"requested": {
"background": 0,
"foreground": 0,
"unset": 0
},
"started_in_background": 0,
"max_depth": 0,
"spawned_by_subagents": 0,
"completed": 0,
"failed": 0,
"killed": {
"parent": 0,
"user": 0,
"system": 0
},
"refused": {
"depth_limit": 0,
"concurrency_limit": 0,
"budget": 0
},
"by_type": {}
},
"safety_stops": 0,
"is_error": false,
"num_turns": 4,
"subtype": "success",
"api_error_status": null,
"result": "I rewrote all four functions in `textnorm.py`. I ran a quick spot-check of your examples and a few extra cases, but I haven't written a test file.\n\nWhat the check showed:\n- **`canonical_username`**: `\" \uff2a\uff4f\uff48\uff4e_Doe \"` gives `john_doe`, and `stra\u00dfe` gives `strasse`. `\u0394\u03b7\u03bc\u03ae\u03c4\u03c1\u03b7\u03c2` gives `\u03b4\u03b7\u03bc\u03ae\u03c4\u03c1\u03b7\u03c3`, and `p\u0430ypal` with a Cyrillic `\u0430` raises `ValueError` for mixing scripts.\n- **`slugify`**:\n - 20 \u00d7 `\"word \"` gives 12 words joined by `-`.\n - `\"abc \" + 70 \u00d7 \"y\"` gives `abc`.\n - 70 \u00d7 `\"x\"` gives 60 characters.\n - `\"\u00c6on \u00de \u00df!\"` gives `aeon-th-ss`, and `\"!!\"` gives `n-a`.\n- **`truncate`**:\n - `hello world` at width 8 gives `hello w\u2026`.\n - Three flag emoji at width 4 keep one whole flag, `\ud83c\uddeb\ud83c\uddf7\u2026`.\n - `\u65e5\u672c\u8a9e\u30c6\u30ad\u30b9\u30c8` at width 6 gives `\u65e5\u672c\u2026`.\n - Width 0 gives `\"\"`.\n - A family emoji that doesn't fit is dropped whole rather than split.\n- **`display_width`**: I didn't print any widths. It follows your rules, including zero width for control characters.\n\nWhere your spec was silent, I made these choices:\n- **ZWJ in `truncate`**: a ZWJ pulls the character after it into the same unit, so a ZWJ emoji sequence is kept or dropped as a whole.\n- **Skin-tone modifiers**: these are not treated as extenders, since you didn't list them.\n- **Uppercase `\u1e9e` in `slugify`**: it maps to `ss` along with the other uppercase forms.",
"ttft_ms": 1734,
"type": "result",
"duration_ms": 32853,
"uuid": "[REDACTED]",
"ttft_stream_ms": 1014,
"time_to_request_ms": 243,
"first_content_frame_ms": 1015,
"queued_turn_count": 0,
"result_index": 0
}
]