fix(deep-interview): canonicalize Hangul before hashing and capping prose - #3872
Merged
Yeachan-Heo merged 3 commits intoAug 6, 2026
Conversation
yazzang-homelab
force-pushed
the
fix/deep-interview-hangul-normalization
branch
2 times, most recently
from
August 5, 2026 13:17
a1c91b9 to
a366111
Compare
…rose Hangul reaches the interview in both composed and decomposed form, so the same Korean answer produced two different answer_hash values: the documented append-or-merge no-op became a duplicate round, and intent-review approval evidence stopped matching the user's own recorded answer. Code-point caps also charged decomposed Hangul two to three units per syllable, so a Korean user_response was rejected at roughly a third of the advertised budget. Yeachan-Heo#3716 only asked models for literal UTF-8 in tool inputs; nothing in the runtime canonicalized user prose. Normalizing at the identity and length boundaries fixes both without touching stored English transcripts. Lore-id: 7c41d0a9 Constraint: stored round prose must stay byte-stable for existing NFC state Rejected: normalize only inside the hash | leaves NFD text in durable state Rejected: normalize in deepInterviewCharacterCount | hides it from callers Confidence: high Scope-risk: narrow Reversibility: easy Tested: NFC/NFD question and answer identity, append-or-merge no-op, cap parity Not-tested: real macOS clipboard capture of decomposed Hangul Refs: Yeachan-Heo#3871
yazzang-homelab
force-pushed
the
fix/deep-interview-hangul-normalization
branch
from
August 5, 2026 23:24
a366111 to
392401c
Compare
Contributor
Author
|
Rebased onto current Re-verified on the new base: |
added 2 commits
August 6, 2026 10:31
Owner
|
This item is being moved to the Tier 3 review lane. Further review is deferred until after the current emergency stabilization period. — |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Canonicalize deep-interview prose to NFC at the identity and length boundaries:
questionHash(),answerHash(),buildAnswerShell()(storedquestion_text/selected_options/custom_input), andassertDeepInterviewInputWithinLimit().Why
Fixes the first half of #3871.
Hangul reaches the interview in both composed (NFC) and decomposed (NFD) form — macOS-sourced pastes and several clipboard/IME paths emit NFD — and the two forms are one text for the user but two different JavaScript strings for us:
That produced three Korean-only failures:
appendOrMergeRound()saw a differentanswer_hashfor the same answer, so its documentednoopbecame a duplicate/replaced round — one answer, two round histories.assertDeepInterviewIntentReview()matches approval evidence byanswer_hashagainst recorded answers, so crossing a normalization boundary invalidated the user's own approval.MAX_USER_RESPONSE_LENGTH = 10_000rejected Korean answers at roughly a third of the advertised budget while ASCII prose got the full 10,000.#3716 asked models for literal UTF-8 in tool inputs, but it is a prompt directive; nothing in the runtime canonicalized user prose. This is the code-level half.
Testing
packages/coding-agent/test/deep-interview-hangul-normalization.test.ts— 5 tests: fixtures are genuinely distinct strings, one question identity across forms, one answer identity for both selected options and custom input,appendOrMergeRoundreturnsnoopwith a single round when both forms arrive, and cap parity (10,000 composed and decomposed both pass; 10,001 decomposed throws).Also verified as not the cause and left untouched: replaying all 173 Korean
askquestions from the local session corpus throughrenderDeepInterviewAskQuestion()/formatDeepInterviewSelectorPrompt()at widths 40–100 loses no Hangul and drifts no padding, so #1996 holds.GJC verdict
devbun checkpasses (bun --cwd=packages/coding-agent run check)