test(language): pin how far the reply guards reach #302

Merged
coilysiren merged 2 commits from test/language-scope-characterization into main 2026-08-13 08:25:16 +00:00
Member

Groundwork for #298, which binds a channel to a language. That makes the reach of the reply guards a shipping question, and the measured answer is English only.

Matched pairs, the same violation written twice

violation          | English   | French
-------------------|-----------|--------
first person       | caught    | MISSED
collective voice   | caught    | MISSED
social opening     | caught    | MISSED
ongoing work       | caught    | MISSED
personality        | caught    | MISSED

ValidateNeutralStyle and ValidateGrounding match English words. Only two rules survive translation and both are character rules: the exclamation ban and the decorative-symbol scan.

So configuring a channel as French would not merely change the output language. It would turn the semantic guards off for that channel, quietly.

The confound is pinned on purpose

Natural French ends an exclamation with " !". My first probe used realistic phrasing, everything came back rejected, and it looked like the guards working — the exclamation rule had fired. The third test asserts that masking behaviour explicitly, because it is the reason this gap is easy to spot-check wrong.

Characterization, not a demand

The rows assert today's behaviour, so CI stays green and honest about what ships. Each carries otherShouldBeCaught: true and names 298 with the condition to flip it, in the same shape as groundingcorpus_test.go.

The English half is asserted separately. Without that, a row could go quiet and the French miss would read as parity rather than as two dead checks.

Verified both directions

mutation result
French pronouns added to the first-person pattern rows trip with the flip instruction
English first-person check disabled vacuity guard trips

This does not implement anything or take a position on how 298 should be built. It makes "this language is guarded" a measurable claim instead of an assumption, and it fails loudly the moment that changes in either direction.

Tests only. No production code changes.

Groundwork for https://forgejo.coilysiren.me/coilyco-gaming/sirens-echo/issues/298, which binds a channel to a language. That makes the reach of the reply guards a shipping question, and the measured answer is **English only**. ## Matched pairs, the same violation written twice ``` violation | English | French -------------------|-----------|-------- first person | caught | MISSED collective voice | caught | MISSED social opening | caught | MISSED ongoing work | caught | MISSED personality | caught | MISSED ``` `ValidateNeutralStyle` and `ValidateGrounding` match English words. Only two rules survive translation and both are **character** rules: the exclamation ban and the decorative-symbol scan. So configuring a channel as French would not merely change the output language. It would turn the semantic guards off for that channel, quietly. ## The confound is pinned on purpose Natural French ends an exclamation with `" !"`. My first probe used realistic phrasing, everything came back rejected, and it looked like the guards working — the exclamation rule had fired. The third test asserts that masking behaviour explicitly, because it is the reason this gap is easy to spot-check wrong. ## Characterization, not a demand The rows assert **today's** behaviour, so CI stays green and honest about what ships. Each carries `otherShouldBeCaught: true` and names 298 with the condition to flip it, in the same shape as `groundingcorpus_test.go`. The English half is asserted separately. Without that, a row could go quiet and the French miss would read as parity rather than as two dead checks. ## Verified both directions | mutation | result | | --- | --- | | French pronouns added to the first-person pattern | rows trip with the flip instruction | | English first-person check disabled | vacuity guard trips | This does not implement anything or take a position on how 298 should be built. It makes "this language is guarded" a measurable claim instead of an assumption, and it fails loudly the moment that changes in either direction. Tests only. No production code changes.
test(language): pin how far the reply guards reach
Some checks failed
ci / test (pull_request) Failing after 30s
ci / publish-echo-image (pull_request) Has been skipped
ci / publish-observed (pull_request) Has been skipped
ci / image-build (pull_request) Successful in 15s
77bbf25c55
Issue 298 binds a channel to a language. That makes the reach of the
reply guards a shipping question, and the answer is that they reach
English only.

Matched pairs, the same violation written twice:

  first person       caught in English, missed in French
  collective voice   caught in English, missed in French
  social opening     caught in English, missed in French
  ongoing work       caught in English, missed in French
  personality        caught in English, missed in French

Only two rules survive translation and both are character rules: the
exclamation ban and the decorative-symbol scan. Every semantic rule is
keyed to English vocabulary.

That matters for how this gets tested by hand. Natural French ends an
exclamation with " !", so a realistic sample comes back rejected and
looks like the guards working. The third test pins that confound
explicitly, because it is the reason the gap is easy to miss.

Characterization, not a demand. The rows assert today's behavior so CI
stays green and honest, and each names 298 with the condition to flip it.
The English half is asserted separately, or a row could go quiet and the
miss would read as parity.

Verified both directions: adding French pronouns to the first-person
pattern trips the rows with the flip instruction, and disabling the
English check trips the vacuity guard.

Tests only. No production code changes.

Refs #298

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-authored-by: Kai Siren <coilysiren@gmail.com>
Co-authored-by: Claude <noreply@anthropic.com>
Author
Member

CI red here is inherited, not from this branch. pre-commit fails on origin/main itself, so every open PR fails the same way.

I checked before assuming: rebased onto main, ran the full suite and every hook. The only failures are in docs/sirens-echo-battery.md, internal/community/evaluation.go, internal/community/evaluation_checks.go, and internal/community/evaluation_checks_test.go — none of which this branch touches. Its own tests pass.

Fixed in #303, which is green. This goes green on a rebase once that merges.

No action needed here.

CI red here is **inherited, not from this branch.** `pre-commit` fails on `origin/main` itself, so every open PR fails the same way. I checked before assuming: rebased onto main, ran the full suite and every hook. The only failures are in `docs/sirens-echo-battery.md`, `internal/community/evaluation.go`, `internal/community/evaluation_checks.go`, and `internal/community/evaluation_checks_test.go` — none of which this branch touches. Its own tests pass. Fixed in https://forgejo.coilysiren.me/coilyco-gaming/sirens-echo/pulls/303, which is green. This goes green on a rebase once that merges. No action needed here.
coilyco-ops force-pushed test/language-scope-characterization from 77bbf25c55
Some checks failed
ci / test (pull_request) Failing after 30s
ci / publish-echo-image (pull_request) Has been skipped
ci / publish-observed (pull_request) Has been skipped
ci / image-build (pull_request) Successful in 15s
to 65bbc1717a
Some checks failed
ci / test (pull_request) Failing after 34s
ci / publish-echo-image (pull_request) Has been skipped
ci / publish-observed (pull_request) Has been skipped
ci / image-build (pull_request) Successful in 20s
2026-08-13 08:15:57 +00:00
Compare
fix(test): keep the language rows past the repo's own linters
All checks were successful
ci / test (pull_request) Successful in 30s
ci / publish-echo-image (pull_request) Has been skipped
ci / publish-observed (pull_request) Has been skipped
ci / image-build (pull_request) Successful in 16s
316c24bd41
Two hook failures, both mine. A 3-line comment where the cap is 2, and
the typo linter reading French "maintenant" as "maintenance".

The second one is the finding this file records, arriving one layer up:
the spell checker is English-only too. Reworded rather than exempted,
since one word is not worth a rule, but issue 298 will need an answer
for this the moment French strings become routine.

Co-authored-by: Kai Siren <coilysiren@gmail.com>
Co-authored-by: Claude <noreply@anthropic.com>
Author
Member

Rebased onto green main and pushed. Both hook failures on the last push were mine, not inherited: a 3-line comment where the cap is 2, and one I did not anticipate.

The typo linter read the French maintenant as a misspelling of maintenance.

That is this PR's own finding arriving one layer up — the spell checker is English-only too. I reworded rather than adding an exemption, because one word is not worth a rule. It is worth recording on #298 though: the moment French strings become routine, _typos.toml needs an answer for them, and that is a third surface beyond the harness messages and the reply guards.

Full suite and every hook pass locally.

Rebased onto green main and pushed. Both hook failures on the last push were mine, not inherited: a 3-line comment where the cap is 2, and one I did not anticipate. The typo linter read the French `maintenant` as a misspelling of `maintenance`. That is this PR's own finding arriving one layer up — **the spell checker is English-only too.** I reworded rather than adding an exemption, because one word is not worth a rule. It is worth recording on https://forgejo.coilysiren.me/coilyco-gaming/sirens-echo/issues/298 though: the moment French strings become routine, `_typos.toml` needs an answer for them, and that is a third surface beyond the harness messages and the reply guards. Full suite and every hook pass locally.
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
coilyco-gaming/sirens-echo!302
No description provided.