afrikaans: a word-final ⟨c⟩ is [k], not the soft [s] (#757) - #759
Merged
Conversation
The rule is "soft [s] BEFORE a front vowel". Word-finally there is no following vowel, so the soft
branch cannot apply — but it did, because the test was `"eiyêéè".includes(w[i + 1] ?? "")` and
includes("") is TRUE for any string. franc→frans, arc→ars, bloc→blɔs.
#756 preserved that verbatim, correctly: a data move must not change output. Deciding it needed the
phonological call, and the call is that the accident INVERTED the rule rather than extending it — no
following letter means the soft condition is unmet, not met.
⚠ NOT REFEREE-CONFIRMED, and it cannot be: af.wiktionary-af.tsv has no word-final ⟨c⟩ at all — its 20
⟨c⟩ entries are surnames (Coetzee, Terblanche), ⟨ch⟩ words, and the letter name C→sɪə. af is unmoved at
1658/2220, exactly as predicted. The goldens pin the rule being self-consistent, and say so.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012Lc3WnUgogC7okV7n53vjr
… the conclusion was not I wrote that af.wiktionary-af.tsv contains no word-final ⟨c⟩, and that its C→sɪə entry reaches output through the initialism path. Both false. The entry IS a word-final ⟨c⟩, eval.ts feeds af through phonemizeWord directly, and the initialism normalizer only fires on runs of two or more letters — so that entry traverses this exact branch, going s→k with this change. The conclusion survives: it misses both ways against sɪə, which is why the folded backbone is unmoved at 1658/2220. But the stated reason would have told the next reader that nothing exercises the branch, which is the opposite of true. My original grep was case-sensitive and lowercase-only; I then saw the C entry in later output and explained it away with an assumption I never checked. Filed the underlying gap as #761: a bare single letter is read as a sound rather than spelled as its name (B→p too), because the initialism normalizer needs ≥2 letters. Also moved the new test into the g2p describe block, where it belongs. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012Lc3WnUgogC7okV7n53vjr
christopherthompson81
force-pushed
the
afrikaans-final-c
branch
from
August 8, 2026 15:12
c37d3b8 to
b7a68b7
Compare
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.
Closes #757.
The call
The rule is "soft [s] BEFORE a front vowel". Word-finally there is no following vowel, so the soft branch cannot apply — but it did:
franc → frans,arc → ars,bloc → blɔs. #756 preserved that verbatim, correctly — a data move must not change output — and left the decision to this issue.The decision is that the accident inverted the rule rather than extending it: no following letter means the soft condition is unmet, not met. That is an argument from the rule's own statement, and it needs no corpus.
⚠ Not referee-confirmed, and it cannot be
Both halves of that were wrong — see the addendum.af.wiktionary-af.tsvcontains no word-final ⟨c⟩ at all… the letter nameC → sɪəreaches output through the initialism path, not this rule.The corpus's one word-final ⟨c⟩ is the letter name
C → sɪə, and it does traverse this branch. It simply misses both ways (s, nowk, againstsɪə), which is why the score is unmoved.So
afis unmoved at 1658/2220 (74.7%), exactly as predicted. The new goldens pin the rule being self-consistent and say so in the comment; they are not evidence of a measured improvement, and shouldn't be read as one.Found along the way, deliberately not bundled: #758
The ⟨c⟩ code rule runs before the fixed table, so
"ch": "ʃ"never fires —chemie → kɦiəmi,chirurg → kɦirœrχ.kɦ-is not a possible Afrikaans onset, and unlike #757 this one is referee-visible.I measured the naive fix (let the digraph win): +1 word, but it breaks
Christus → ʃrəstœs(should be [kr-]) and pusheschemieto [ʃ] where the referee wants [x]. Afrikaans ⟨ch⟩ is three sounds by source — [ʃ] French, [x] Greek/Dutch, [k] before ⟨r⟩ — so it needs a conditioning decision, not a reordering. Filed as #758 with those numbers so the next attempt starts from data.npm run cigreen — 228 files / 3141 tests.🤖 Generated with Claude Code
https://claude.ai/code/session_012Lc3WnUgogC7okV7n53vjr
Review addendum — my stated reason was false
I claimed the referee holds no word-final ⟨c⟩, and that its
C → sɪəentry reaches output via the initialism path. Both wrong, and the review caught it:Cis a word-final ⟨c⟩, andeval.tsfeedsafthroughphonemizeWorddirectly, with no normalization pass — so that entry goes through this exact branch,s→kwith this change.Cnever reaches it.My original grep was case-sensitive and lowercase-only. I then saw the
Centry in later output and explained it away with an assumption I never checked — the same shape of error as the "corpus isn't in-repo" claim in #748.The conclusion survives:
sandkboth miss againstsɪə, so the folded backbone is unmoved at 1658/2220 and this change remains rule-consistency rather than a measured gain. But the reason has been corrected in the test comment, because as written it would have told the next reader that nothing exercises the branch.The underlying gap — a bare single letter read as a sound instead of spelled as its name (
C → k,B → p) — is filed as #761.Test also moved into the g2p
describeblock, where it belongs.