fix: admin healthcheck IPv6 + single-word distractor prompt#233
Merged
Conversation
Two narrow fixes surfaced after the gemma4:e4b deploy.
1. admin healthcheck used localhost which Alpine resolves to ::1 (IPv6)
first; vite binds only to 0.0.0.0 (IPv4) so wget got "Connection
refused" forever. textstack_admin_prod has been (unhealthy) with
FailingStreak=241 since deploy. Switched to 127.0.0.1.
2. DistractorGenerator's parser drops multi-word entries
(`!w.Contains(' ')`). Gemma4 likes phrasal distractors ("strong
consistency", "data loss") so most of its output gets stripped and
the 5-distractor minimum fails — falls back to random vocab words.
Added explicit single-word instruction with concrete examples.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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.
Two narrow fixes surfaced after the gemma4:e4b deploy
1. `admin` container has been (unhealthy) since deploy
Symptom: `textstack_admin_prod` shows `(unhealthy)` with `FailingStreak=241` (= 2 hours of consecutive 30s checks failing). Healthcheck output: `wget: can't connect to remote host: Connection refused`.
Root cause: healthcheck does `wget http://localhost:81\`. In Alpine `localhost` resolves to `::1` (IPv6) first. Vite binds only to `0.0.0.0` (IPv4) per `pnpm dev --host 0.0.0.0`. wget tries IPv6 → connection refused.
Fix: `localhost` → `127.0.0.1` (single line in `docker-compose.yml`).
Verified on prod:
```
docker exec textstack_admin_prod wget -qO- http://localhost:81/ # → Connection refused
docker exec textstack_admin_prod wget -qO- http://127.0.0.1:81/ # → returns HTML
```
API healthcheck has the same `localhost` text but is fine because Kestrel binds both IPv4+IPv6 by default. Only Vite is affected.
2. Gemma4 distractor output gets stripped
Symptom: smoke tested `gemma4:e4b` for "eventual consistency" — it returned `["strong consistency", "read-after-write", "data loss", ...]`. After `ParseWordList`'s `!w.Contains(' ')` filter, only `read-after-write` and `causality` survive. `distractors.Count >= 3` fails → fallback to random vocab pool words.
Root cause: Gemma4 prefers phrasal answers; the parser is built for single tokens (existing constraint, not introduced by the model swap — but the swap surfaces it).
Fix: prompt now explicitly demands SINGLE-WORD distractors with concrete examples (`linearizability` not `strong consistency`). Hyphens still allowed since the parser permits them.
This keeps the existing parser logic intact (no risk of letting phrasal noise through) while giving the LLM clear guidance.
Test plan
🤖 Generated with Claude Code