Skip to content

Add a new mod named Chinese Character Natural Sort - #5019

Open
llw1573 wants to merge 2 commits into
ramensoftware:mainfrom
llw1573:main
Open

Add a new mod named Chinese Character Natural Sort#5019
llw1573 wants to merge 2 commits into
ramensoftware:mainfrom
llw1573:main

Conversation

@llw1573

@llw1573 llw1573 commented Aug 5, 2026

Copy link
Copy Markdown

Hi! This PR introduces Chinese Character Natural Sort, a new mod that fixes a long-standing frustration for Chinese Windows users.

The Problem:
By default, Windows sorts Chinese characters alphabetically by their Pinyin pronunciation. This completely breaks sequential file numbering (e.g., under Pinyin rules, (2/Er) < (3/San) < (1/Yi), resulting in chaotic file orders).

The Solution:
This mod hooks CompareStringEx, CompareStringW, and StrCmpLogicalW to introduce a custom logical sorting algorithm. It intelligently parses Chinese numerals (including complex multi-digit numbers and uppercase variants like 壹/拾/佰), Heavenly Stems, and traditional volume indicators (上/中/下).

Performance & Safety:
Since it uses @include * for system-wide support (Explorer, Open/Save dialogs, etc.), I added a strict performance bypass (if (c < 0x3000) return CAT_NONE;). This ensures that standard ASCII/English strings are instantly passed back to the native Windows API, resulting in zero measurable performance overhead for non-Chinese text.

Thanks for reviewing!

Mod authorship

If this pull request introduces a new mod, please complete the section below.

This mod was created by:

    • The submitter, without AI assistance
    • The submitter, with AI assistance
    • Claude
    • ChatGPT
    • Gemini
    • Another AI (please specify):
    • Other (please specify):

Please select the options that best apply. Your selection does not affect the acceptance criteria, but it helps reviewers understand the context of the code and provide relevant feedback.

chinese-logical-sort is a mod for provides natural sorting for Chinese file names.
@windhawk-reviewer

Copy link
Copy Markdown

Thanks for the pull request! This repository uses a two-stage review: an AI review that you run yourself, followed by a human review.

To get started, comment /ai-review. Once you're happy with the result, comment /ready-for-reviewer to hand it over to a human reviewer.

See the pull request review process for the full details.

@windhawk-reviewer windhawk-reviewer Bot added the waiting-for-author The author's turn: request an AI review, or respond to one that was posted. label Aug 5, 2026
@llw1573

llw1573 commented Aug 5, 2026

Copy link
Copy Markdown
Author

/ai-review

@windhawk-reviewer windhawk-reviewer Bot added waiting-for-ai-review An AI review was requested and is being prepared. and removed waiting-for-author The author's turn: request an AI review, or respond to one that was posted. labels Aug 5, 2026
@llw1573 llw1573 changed the title update a new mod Add a new mod named Chinese Character Natural Sort Aug 5, 2026
@windhawk-reviewer

Copy link
Copy Markdown

Submission review

Note: This review was done by Claude. Due to the amount of submissions, doing a fully manual review for each pull request is no longer feasible. Thank you for understanding.

Remember: The AI reviewer can be wrong - it may misread code, flag correct code as broken, or suggest changes that make things worse. Treat its findings as suggestions to verify, not instructions to follow blindly. You're responsible for the code you submit, so if a finding doesn't hold up, say so instead of changing working code to satisfy it.

Please address the following issues. The items in the collapsed sections are optional, so it's your call whether to address them.


The idea is sound and there's no existing mod that does this, but the current implementation has a hard hang, changes comparison semantics for non-Chinese text, and hooks two of the most fundamental Windows APIs in every process. Details below.

1. Infinite loop (process hang) on file names starting with

GetCategory classifies as CAT_NUMBER (it's in the string on line 100), but ParseChineseNumber has no case for it — the 2 case only handles and . So for the parser hits else break; on the first character, found stays false, and it returns -1 with parsedLen = 0.

In CustomCompare, when both sides fail to parse:

if (val1 != -1 && val2 != -1 && val1 != val2) { ... }
else {
    if (l1 == l2 && wcsncmp(lpString1 + i, lpString2 + j, l1) == 0) {
        i += l1; j += l2; continue;   // l1 == l2 == 0  ->  no progress
    }

l1 == l2 == 0, and wcsncmp(p1, p2, 0) returns 0, so i and j are never advanced and the while loop spins forever. Comparing 贰月.txt with 贰号.txt (or any string against itself starting with ) hangs the calling thread at 100% CPU — in Explorer that means the whole window locks up, and since this is @include * it can happen in any process.

Two fixes are needed:

  • Add (and ideally the traditional ) to ParseChineseNumber.
  • Add an unconditional progress guard so a future mismatch between the category table and the parser can't hang again:
if (l1 == 0 || l2 == 0) return 0;   // nothing consumed -> defer to the OS

2. The hooks change ordering for plain ASCII/Arabic-digit strings, in every process

CompareStringW / CompareStringEx sort digits as characters unless the caller passes SORT_DIGITSASNUMBERS. The mod applies numeric ordering unconditionally, so CompareStringW(locale, 0, L"item10", -1, L"item9", -1) now returns CSTR_GREATER_THAN where Windows returns CSTR_LESS_THAN — an inverted result for a call that has nothing to do with Chinese. This contradicts the PR description ("standard ASCII/English strings are instantly passed back to the native Windows API"): the CAT_ARABIC branch actively decides for them.

These APIs aren't only used for display sorting — CompareStringEx backs .NET's culture-aware String.Compare/CompareInfo, sorted collections, and binary searches over pre-sorted tables. Silently switching those to numeric ordering system-wide can produce wrong lookups in unrelated applications.

Suggested fix: in the CompareStringW/CompareStringEx hooks, use the Arabic branch only to skip over identical digit runs, never to return a decision (return 0 and defer to the original when the values differ), unless dwCmpFlags & SORT_DIGITSASNUMBERS is set. StrCmpLogicalW is a different case — numeric ordering is its documented behavior, so deciding there is fine.

3. dwCmpFlags and the requested locale are ignored

CustomCompare never looks at dwCmpFlags, lpLocaleName or Locale, and the prefix-skip loop is unconditionally case-insensitive:

if (towlower(lpString1[i]) == towlower(lpString2[j])) { i++; j++; continue; }

So a case-sensitive comparison (dwCmpFlags == 0) walks past A/a as if they were equal and then decides on a later character — CompareStringW(LOCALE_INVARIANT, 0, L"A一", -1, L"a二", -1) returns CSTR_LESS_THAN, while Windows returns CSTR_GREATER_THAN because the case difference is decisive at the first character. The same applies to NORM_IGNORESYMBOLS, NORM_IGNORENONSPACE, SORT_STRINGSORT etc., and to callers that explicitly ask for an invariant/ordinal-ish comparison and don't expect locale-specific reordering at all.

Minimum fix: use an exact lpString1[i] == lpString2[j] for the skip (which is also faster than a CRT towlower call per character), and bail out to the original whenever dwCmpFlags contains flags you haven't accounted for.

4. The comparator isn't transitive, so the resulting order can be arbitrary

Because the mod decides some pairs itself and delegates the rest to the OS, the combined comparator has cycles. Concrete example with the 上/中/下 category (Windows pinyin order is (xia) < (yang) < (zhong)):

  • vs — different categories → delegated → 下 < 羊
  • vs — different categories → delegated → 羊 < 中
  • vs — both CAT_SHANGZHONGXIA → mod decides 中 < 下

下 < 羊 < 中 < 下. A comparator like this makes sort output depend on the comparison order the algorithm happens to use (and is undefined behavior for std::sort), so file lists can come out in an order that looks random rather than merely "different".

The clean fix is to make the mod produce a sort key instead of a partial verdict: rewrite each string into a canonical form (recognized Chinese numeral runs → zero-padded ASCII digits, 甲乙丙…a01, a02, …, 上中下s1, s2, s3), then call the original comparison function on the two transformed strings. An ordering induced by a deterministic key mapping plus the native collation is automatically consistent and transitive, and it also inherits the correct handling of flags and locale from item 3.

5. Reconsider hooking CompareStringW/CompareStringEx at all, and the @include * scope

Explorer and the common file dialogs sort file names through StrCmpLogicalW (windows.storage.dll!CFSFolder::CompareIDs and friends), which is by definition a display-sort comparator — overriding it is low risk. CompareStringW/CompareStringEx are general-purpose NLS APIs used by every application for program logic, and overriding them in every process on the system is a much larger blast radius for a benefit that, for the stated use case, StrCmpLogicalW likely already delivers.

Please check whether the StrCmpLogicalW hook alone achieves the goal in Explorer and in Open/Save dialogs. If it does, drop the other two hooks. If you do keep them, consider narrowing @include (e.g. explorer.exe plus the specific apps you care about) and mention in the README that users can add more processes in the mod's advanced settings — see the injection targets page.

6. ParseChineseNumber computes wrong values for common numbers

The if (temp == 0) temp = 1; guard in the /亿 branches is meant for a bare /亿, but it also fires when a section has already been accumulated:

  • 十万section = 10, then forces temp = 1(10 + 1) * 10000 = 110000 instead of 100000
  • 一百万(100 + 1) * 10000 = 1010000 instead of 1000000

This isn't only cosmetic: 十万 (110000) and 十一万 (110000) now compare equal, so the branch falls through to l1 != l2return 0 and the pair is handed back to the OS, i.e. it stays mis-sorted.

Additionally, the 亿 branch double-counts total:

total += (total + section + temp) * 100000000;   // should be: total = (...)

十亿 yields 1100000000 instead of 1000000000.

Suggested fix:

} else if (c == L'' || c == L'') {
    if (section == 0 && temp == 0) temp = 1;
    total += (section + temp) * 10000;
    section = 0; temp = 0;
    found = true;
} else if (c == L'亿' || c == L'') {
    if (total == 0 && section == 0 && temp == 0) temp = 1;
    total = (total + section + temp) * 100000000;
    section = 0; temp = 0;
    found = true;
}

Also, ParseArabicNumber clamps with if (val < LLONG_MAX / 10) but ParseChineseNumber has no clamp — temp = temp * 10 + digit over a long numeral run (e.g. a 20+ character 二〇二四… name), or repeated 亿, overflows a signed long long, which is undefined behavior. Please clamp the same way.

7. Ordinary Chinese words are treated as sequence markers

The mod applies its ordering to any recognized character anywhere in the name, with no requirement that it actually be a sequence number. and are also the first characters of 中国, 中文, 下载; , , , start 一起, 五五开, 千寻, 万能; and the 天干/地支 sets are made of very common characters (, , , , ). So 中国.txt now sorts before 下载.txt, and 一起.txt before 五五开.txt — neither is pinyin order nor what the user asked for, and it applies to every Chinese file name they have, not just numbered ones.

Suggestions: require a numbering context before applying the special ordering (the numeral run is delimited by separators/extension boundaries, or preceded by // and/or followed by ///////), and add a settings block so each category (Chinese numerals, 天干, 地支, 上中下) can be turned off independently. The 上中下 and 天干/地支 categories in particular are much narrower use cases than the numerals and would be reasonable to default to off.

Optional improvements

Minor polish — none of this affects users, so it's your call.

  • Use the type-safe wrapper instead of raw Wh_SetFunctionHook with void* casts — add #include <windhawk_utils.h> and:
    auto pCompareStringEx = (CompareStringEx_t)GetProcAddress(hKernelBase, "CompareStringEx");
    if (pCompareStringEx) {
        WindhawkUtils::SetFunctionHook(pCompareStringEx, CompareStringEx_Hook, &CompareStringEx_Original);
    }
    See add-virtual-folders-to-nav-top.wh.cpp#L2421 for the same pattern.
  • LoadLibraryW(L"shlwapi.dll")LoadLibraryExW(L"shlwapi.dll", nullptr, LOAD_LIBRARY_SEARCH_SYSTEM32) as a habit (shlwapi is a KnownDLL so there's no hijacking risk here, but the explicit form is what other mods use — e.g. classic-desktop-icons.wh.cpp#L489). Better still, try GetModuleHandleW first and only force-load if it's missing — with @include * this currently pulls shlwapi.dll into every process on the system, including ones that never use it. The reference is also never released; a matching FreeLibrary in Wh_ModUninit would avoid leaking one refcount per enable/disable cycle.
  • CSTR_LESS_THAN, CSTR_EQUAL and CSTR_GREATER_THAN are already defined by winnls.h (via windows.h) with the same values — the three #defines at the top are redundant.
  • #include <shlwapi.h> is unused (nothing from it is called directly; the StrCmpLogicalW_t typedef doesn't need it). Conversely, LLONG_MAX is used without including <climits> — better to include it explicitly than to rely on a transitive include.
  • GetCategory does up to five wcschr scans per character. A switch (or a small sorted lookup) would be clearer and faster, and would keep the category table and ParseChineseNumber next to each other so item 1 can't recur.
  • The README would benefit from a before/after screenshot of a folder listing — it's the clearest way to show what the mod does. Only i.imgur.com and raw.githubusercontent.com are allowed as image hosts.
  • Leftover wording: Wh_Log(L"Initializing Modern Chinese Logical Sort mod") says "Modern", and Windhawk already prefixes the mod name in the log.
  • Consider adding @license — it's optional, but most mods declare one.

Functionality notes

Non-critical observations and ideas about the feature behavior itself.

  • Explorer only routes name sorting through StrCmpLogicalW when numerical sorting is enabled (it can be turned off via the NoStrCmpLogical policy), and other columns don't use it at all. Worth verifying the mod behaves as expected in both configurations, and after an Explorer restart / reboot rather than only when enabled mid-session.
  • Mixed Arabic/Chinese numbering (第10章 vs 第九章) falls back to the OS, so those aren't interleaved correctly. The README describes this as intentional; it may be worth stating explicitly as a limitation so users aren't surprised.
  • Some common variants aren't covered: traditional / for 2, 廿/ (20/30), and combined 干支 pairs (甲子, 乙丑, …) which form a 60-cycle rather than two independent sequences.
  • / is treated as a positional digit (二〇二四 → 2024) and as zero inside a section (一百零一 → 101), which happens to work for both, but a year-style string and an arithmetic-style string end up in the same numeric space — e.g. 二〇二四 (2024) will interleave with 二千零二十四 (2024) only because both resolve to the same value, while 一〇 (10) and (10) do too but then fall back to the OS because the lengths differ. Worth deciding deliberately which reading wins.


Next steps:

  • /ai-review - after pushing fixes, to get a review of the updated code. You can repeat this as many times as you need, but each review is thorough and usually there's no need for more than 2-3 iterations.
  • /ready-for-reviewer - once you're satisfied with the state of the pull request, to hand it over to a human reviewer. If some findings above are left unaddressed, add a short note explaining why.

See the review process for details.

@windhawk-reviewer windhawk-reviewer Bot added waiting-for-author The author's turn: request an AI review, or respond to one that was posted. and removed waiting-for-ai-review An AI review was requested and is being prepared. labels Aug 5, 2026
Claude pointed out some of my errors, and I corrected them.
@llw1573

llw1573 commented Aug 5, 2026

Copy link
Copy Markdown
Author

/ai-review

@windhawk-reviewer windhawk-reviewer Bot added waiting-for-ai-review An AI review was requested and is being prepared. and removed waiting-for-author The author's turn: request an AI review, or respond to one that was posted. labels Aug 5, 2026
@windhawk-reviewer

Copy link
Copy Markdown

Submission review

Note: This review was done by Claude. Due to the amount of submissions, doing a fully manual review for each pull request is no longer feasible. Thank you for understanding.

Remember: The AI reviewer can be wrong - it may misread code, flag correct code as broken, or suggest changes that make things worse. Treat its findings as suggestions to verify, not instructions to follow blindly. You're responsible for the code you submit, so if a finding doesn't hold up, say so instead of changing working code to satisfy it.

Please address the following issues. The items in the collapsed sections are optional, so it's your call whether to address them.


The parser itself is solid (overflow-checked, the gates keep false positives down, the reentrancy guard correctly prevents StrCmpLogicalWCompareStringW recursion, and resolving the exports from kernelbase.dll is the right choice). The problems are in when the mod decides to override Windows, and in how wide the override is.

1. The mod overrides Windows' ordering for names that have nothing in common, contradicting the documented fallback. In Compare, a mismatch of token kinds is decided by the enum order (K_NUM=1K_TEXT=6):

if (ta[k].kind != tb[k].kind) {
    *handled = true;
    return ta[k].kind < tb[k].kind ? -1 : 1;
}

A name with no recognized ordinal tokenizes to a single K_TEXT token, so every name whose first token is a Chinese ordinal now sorts before every other name:

  • 一月.txt vs 会议记录.txt → mod puts 一月.txt first (Windows: 会议记录 first, hui < yi).
  • 一月.txt vs 2月.txt → mod puts 一月.txt first, even though the README explicitly promises the opposite: "If characters belong to different systems (e.g., Arabic numerals vs. Chinese numerals), it safely falls back to the native Windows sorting behavior."
  • 上万.txt vs 上海.txt上万 tokenizes as TEXT("上") + NUM(10000), so the decision is made by comparing the segment against the whole string 上海.txt上万 first (Windows: 上海 first, hai < wan).

The same applies to the na != nb rule and to the K_TEXT segment comparisons: they take the decision away from Windows even though the mod has no ordinal information to add. That rule additionally ignores the caller's dwCmpFlags — with e.g. NORM_IGNORESYMBOLS, CompareStringEx(…, L"一。", -1, L"一", -1) returns CSTR_EQUAL natively, but the mod reports "greater" because na != nb. Callers that use CompareString* as an equality test then get a false "not equal".

Suggested rule: take over only when the first difference is a pair of same-kind ordinal tokens with different values, and otherwise leave *handled = false so Windows decides the whole comparison with its original flags:

for (int k = 0; k < n; k++) {
    if (ta[k].kind != tb[k].kind) return 0;   // different systems -> native
    if (ta[k].kind != K_TEXT) {
        if (ta[k].val != tb[k].val) {
            *handled = true;
            return ta[k].val < tb[k].val ? -1 : 1;
        }
        continue;
    }
    if (segCmp(ctx, a + ta[k].off, ta[k].len, b + tb[k].off, tb[k].len) != 0)
        return 0;                             // text differs -> native
}
return 0;                                     // including na != nb

第一章 vs 第二章, 一月 vs 十二月, 第九十九 vs 第一百二十三 all still work (the first difference is a same-kind K_NUM pair), equality and flag handling stay exactly as Windows defines them, and unrelated names keep their native order — which is what the README claims today.

2. Hooking CompareStringW / CompareStringEx in every process by default is too broad. @include * is fine per se, but hook_comparestring defaults to true, and those two functions are the system's general-purpose collation primitives — not filename APIs. Every process on the machine then gets a modified sort order for sorted containers, binary searches over pre-sorted tables, $options-style lookup lists, IME candidate lists, and any app's sorted UI. One concrete inconsistency: LCMapStringEx(LCMAP_SORTKEY) is not hooked, so code that sorts with sort keys and then searches with CompareStringEx ends up with two disagreeing orders, which silently turns into failed lookups rather than a visible bug.

Your own setting description already says StrCmpLogicalW is what Explorer's file list uses — overriding a function whose documented job is literally "natural sort order" is far easier to defend than overriding CompareStringEx. So please default hook_comparestring to false (opt-in for people who want the broader effect), and consider whether the @include list can be narrowed to the processes you actually care about (explorer.exe at minimum; users can add more in the mod's advanced settings) — with the note that * is needed if you want it in every app's file dialog.

3. The TLS index is leaked on unload. TlsAlloc in Wh_ModInit has no matching TlsFree, and Wh_ModUninit only logs. In a long-lived host such as explorer.exe, every disable/enable, settings-driven reload, or mod update permanently burns one of the process's TLS slots. The simplest fix is to drop the manual TLS entirely and use thread_local, as other mods do for exactly this reentrancy-guard pattern (start-menu-size.wh.cpp#L625):

thread_local bool g_inHook;

static bool GuardEnter() {
    if (g_inHook) return false;
    g_inHook = true;
    return true;
}

static void GuardLeave() { g_inHook = false; }

That also removes the GetLastError/SetLastError dance those two helpers need today, and the TLS_OUT_OF_INDEXES fallback path. If you prefer to keep TlsAlloc, add TlsFree(g_tlsDepth) to Wh_ModUninit.

4. Please add a screenshot to the README. The whole point of the mod is a visible change in file ordering, and a before/after pair makes it immediately understandable — see how classic-this-pc-sort-order.wh.cpp does it (only i.imgur.com and raw.githubusercontent.com are allowed image hosts).

Optional improvements

Minor polish — none of this affects users, so it's your call.

  • SetHookT re-implements WindhawkUtils::SetFunctionHook, which is already available (you include windhawk_utils.h but otherwise don't use it). The signatures are compatible, so you can delete the template and call WindhawkUtils::SetFunctionHook(pEx, CompareStringEx_Hook, &CompareStringEx_Original) directly.
  • In IsChineseLocaleName, the LOCALE_NAME_USER_DEFAULT branch is dead code: that macro is defined as NULL, so the call is CompareStringOrdinal(name, -1, NULL, -1, TRUE), which just fails with ERROR_INVALID_PARAMETER and returns 0. The nullptr locale case is already handled in TakeoverAllowedEx, so the branch can go. Also, the LOCALE_NAME_SYSTEM_DEFAULT branch answers with g_userLocaleIsChinese; if you want it to be accurate, cache GetSystemDefaultLocaleName separately.
  • There's no Wh_ModSettingsChanged, so the runtime flags (enable_*, only_chinese_locale) are only read once in Wh_ModInit. Adding the simple variant makes toggles apply immediately instead of depending on a reload:
    void Wh_ModSettingsChanged() {
        LoadSettings();  // the Wh_GetIntSetting block, factored out of Wh_ModInit
    }
    (hook_comparestring still needs a reload, since hooks are installed at init — worth saying so in its $description.)
  • With @include *, force-loading shlwapi.dll when it isn't present pulls a DLL (and its DllMain) into processes that never sort anything. Consider using GetModuleHandleW only, and applying the StrCmpLogicalW hook lazily by hooking LoadLibraryExW — resolved from kernelbase.dll, not the kernel32 import, since internal callers go straight to kernelbase:
    HMODULE kernelBase = GetModuleHandleW(L"kernelbase.dll");
    auto pLoadLibraryExW = (decltype(&LoadLibraryExW))GetProcAddress(kernelBase, "LoadLibraryExW");
    WindhawkUtils::SetFunctionHook(pLoadLibraryExW, LoadLibraryExW_hook, &LoadLibraryExW_orig);
    (The LOAD_LIBRARY_SEARCH_SYSTEM32 flag you already pass is correct, so there's no DLL-hijacking issue either way.)
  • #include <shlwapi.h> is unused — you declare your own StrCmpLogicalW_t and resolve it via GetProcAddress. <limits.h> can be <climits> in C++.
  • GanzhiIndex linear-searches all 60 combinations to invert the stem/branch pair. It's called rarely enough that performance doesn't matter, but a closed form or a 60-entry table would read more clearly.

Functionality notes

Non-critical observations and ideas about the feature behavior itself.

  • The "zero measurable performance overhead for non-Chinese text" claim in the PR description isn't quite right. HasCandidate scans both strings end to end on every hooked call, while the native comparison usually returns at the first differing character. For a sort of N items that's O(N log N) full-length scans instead of O(N log N) short-circuited compares. There's no clean way around it (the tokenizer needs to see the whole string), which is another argument for keeping the CompareString* hooks opt-in — inside StrCmpLogicalW on a file list the cost is irrelevant.
  • Heuristic false positives on ordinary words: 百年.txt parses as NUM(100) + , 一天.txt as NUM(1) + , 上万.txt as TEXT(上) + NUM(10000). The gates catch most cases (一起, 万事, 十分, 上海, 中国 all stay text — nice), but not all. Item 1's "only decide on same-kind ordinal differences" rule makes most of the remaining ones harmless, since a mismatch just falls back to Windows. It may still be worth softening the README claim that other files' order is never disturbed.
  • Consecutive digit characters are concatenated positionally, so 一二.txt is 12 and 一二三.txt is 123. That's right for 〇一二-style numbering but wrong if someone writes 一二三 meaning "parts 1, 2, 3" — probably fine, just confirming it's intentional.
  • / (very common colloquial "two", as in 两册) and 廿/ aren't in CnDigit/CnUnit. Cheap to add if you want them.
  • MAX_TOKENS exhaustion degrades silently: once n + 2 > maxTokens, Tokenize stops recognizing ordinals and the rest of the name collapses into one text token, so two very long names can compare inconsistently with shorter ones. 64 tokens make this rare, but a Wh_Log when the budget runs out would make it debuggable.
  • IsWordChar is UTF-16-unaware: surrogate pairs (CJK Ext. B, U+20000 and up) fall into 0xD8000xDFFF and are classified as delimiters, so a rare-character name can satisfy SingleGate/NumGate where it shouldn't. Very much an edge case.


Next steps:

  • /ai-review - after pushing fixes, to get a review of the updated code. You can repeat this as many times as you need, but each review is thorough and usually there's no need for more than 2-3 iterations.
  • /ready-for-reviewer - once you're satisfied with the state of the pull request, to hand it over to a human reviewer. If some findings above are left unaddressed, add a short note explaining why.

See the review process for details.

@windhawk-reviewer windhawk-reviewer Bot added waiting-for-author The author's turn: request an AI review, or respond to one that was posted. and removed waiting-for-ai-review An AI review was requested and is being prepared. labels Aug 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

waiting-for-author The author's turn: request an AI review, or respond to one that was posted.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant