Skip to content

fix(dashboard): normalize Unicode when matching team correction keywords #573

Description

@jeff-r2026

Problem

Team correction keywords introduced in #567 do not match canonically equivalent Unicode text. A French keyword written with a precomposed accented character matches, while the same visible prompt with a combining accent does not. This can undercount course corrections in dashboard/session metrics and affect correction-based contribution nudges.

Reproduction

Configure the team's teamai.yaml:

sharing:
  intervention:
    correctionKeywords: [réessaye]

Dispatch a prompt through the built CLI with either payload (use a valid project cwd or an initialized user-scope config):

{"session_id":"unicode-nfc","prompt":"r\u00e9essaye"}
{"session_id":"unicode-nfd","prompt":"re\u0301essaye"}
teamai hook-dispatch prompt-submit --tool claude < payload.json

Inspect ~/.teamai/dashboard/events.jsonl:

  • NFC prompt: correction: true.
  • NFD prompt: correction: false.

Expected: both prompts match the configured keyword. Both render as “réessaye”. To observe the aggregate count, submit the prompt within 60 seconds after a Stop event in the same session.

Cause and suggested fix

containsKeyword and isCorrectionPrompt in src/dashboard-collector.ts lowercase text but do not normalize Unicode. Normalize both the prompt and configured keywords to NFC before matching. Add regression coverage for both directions (NFC keyword/NFD prompt and NFD keyword/NFC prompt), including aggregate correction counts.

Local validation

Reproduced through the real built CLI across Claude, Codex, CodeBuddy and OpenCode, with local team configurations declaring each of the git, gitlab and github providers. This is a hook-dispatch/event-persistence test; it does not exercise live provider authentication or agent GUIs.

The 108-case matrix had 96 passes and 12 failures, all for the NFD version of this keyword. Existing Spanish false-positive examples, English and Chinese corrections, underscore boundaries, full-prompt matching past 200 characters, and the NFC French keyword passed. A focused regression test also reproduces the failure.

Scope

Follow-up accepted separately from #567. Normalize matching input without changing persisted prompt text or the existing correction time window.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions