Skip to content

Claude Haiku 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 Haiku 5.5default · thinking on · Claude Code 2.1.299 (headless -p) · cloud · 2026-10-17 · by @bobsiopener

Trust 80%Fully autonomoussuccess · first try
Estimated cost
$0.01
Wall time
1m
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-haiku-5.5: $0.012571. 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.01
Wall time
1m
Human step-ins
0
Turns
5
Model usage
ModelInput tokOutput tokCost
AClaude Haiku 5.5anthropic/claude-haiku-5.5effort default (no --effort flag) · thinking on128,75714,277$0.01

Reproduce this run

  1. Use the use case prompt on the use case page.
  2. Same setup: Claude Haiku 5.5 (anthropic/claude-haiku-5.5, effort default (no --effort flag) · thinking on) via Claude Code 2.1.299 (headless -p), cloud.
  3. 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.
  4. 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?

⇄ Rerun on another model

Automated checks

Trust 80% comes from these checks (how Trust % works).

Evidence log
[
 {
  "duration_api_ms": 65839,
  "stop_reason": "end_turn",
  "session_id": "[REDACTED]",
  "total_cost_usd": 0.01257087,
  "usage": {
   "input_tokens": 10,
   "cache_creation_input_tokens": 21810,
   "cache_read_input_tokens": 106937,
   "output_tokens": 14277,
   "output_tokens_details": {
    "thinking_tokens": 10544
   },
   "server_tool_use": {
    "web_search_requests": 0,
    "web_fetch_requests": 0
   },
   "service_tier": "standard",
   "cache_creation": {
    "ephemeral_1h_input_tokens": 21810,
    "ephemeral_5m_input_tokens": 0
   },
   "inference_geo": "global",
   "iterations": [
    {
     "input_tokens": 2,
     "output_tokens": 1358,
     "cache_read_input_tokens": 32894,
     "cache_creation_input_tokens": 1455,
     "cache_creation": {
      "ephemeral_5m_input_tokens": 0,
      "ephemeral_1h_input_tokens": 1455
     },
     "type": "message"
    }
   ],
   "speed": "standard",
   "fallback_credit": null
  },
  "modelUsage": {
   "claude-haiku-5-5": {
    "inputTokens": 10,
    "outputTokens": 14277,
    "cacheReadInputTokens": 106937,
    "cacheCreationInputTokens": 21810,
    "webSearchRequests": 0,
    "costUSD": 0.01257087,
    "contextWindow": 1000000,
    "maxOutputTokens": 128000,
    "thinkingTokens": 10544,
    "canonicalModel": "claude-haiku-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": 5,
  "subtype": "success",
  "api_error_status": null,
  "result": "I rewrote all four functions in `textnorm.py` to the spec. The spec examples pass in ad-hoc checks run against the file. I didn't add a test file to the work directory.\n\nWhat changed:\n\n- **`canonical_username`**: strips the listed format characters, applies NFKC and casefold, then strips whitespace. It checks length (3\u201332), allows only L*, Nd, `.`, `_`, `-`, and raises `ValueError` if letters come from more than one script (judged by the first word of `unicodedata.name`).\n- **`display_width`**: 0 for Mn, Me, Cf and Cc; 2 for East Asian Width W or F; 1 otherwise.\n- **`truncate`**: splits the string into clusters (base character plus marks, variation selectors and ZWJ-joined next character, and regional-indicator pairs), keeps whole clusters that fit, strips any trailing ZWJ, then appends the ellipsis. It returns `\"\"` if the ellipsis alone doesn't fit.\n- **`slugify`**: applies NFKD, drops marks, maps the listed letters (and uppercase forms), lowercases, collapses non-`a-z0-9` runs to `-`, and applies the 60-character word-boundary rule and the `\"n-a\"` fallback.\n\nChoices I made where the spec was silent or ambiguous:\n\n- **Digits-only usernames** such as `\"123\"` are allowed, since no letters means no script conflict.\n- **Slugify marks**: lowercasing can reintroduce a combining mark (`\"\u0130\"` becomes `i` plus U+0307), so I strip marks a second time after lowercasing. Without this, `\"\u0130\"` would become a `-` separator.\n- **Emoji ZWJ sequences** are treated as one unit, so `truncate` never cuts inside a family emoji.\n- **Mc (spacing combining marks)** attach to their base in `truncate`, though they count as width 1 like any other non-zero character.\n\nSpec-literal behaviours you may want to change:\n\n- Letters like `\u00f0` and dotless `\u0131` are not in the slug map, so they become `-`.\n- Modifier letters (category Lm) are judged by their name's first word, for example `MODIFIER`, so mixing one with Latin raises `ValueError`.\n\nThis directory is not a git repository, so I did not commit anything.",
  "ttft_ms": 1744,
  "type": "result",
  "duration_ms": 66269,
  "uuid": "[REDACTED]",
  "ttft_stream_ms": 1550,
  "time_to_request_ms": 289,
  "first_content_frame_ms": 1551,
  "queued_turn_count": 0,
  "result_index": 0
 }
]

Get new runs and ranking changes weekly