Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
e70cebd
feat(portal): the capability gate, and the first surface behind it
emooreatx Aug 28, 2026
80189a6
feat(portal): the /verify surface, and what it says when the node can…
emooreatx Aug 28, 2026
6a781f2
fix(portal): could-not-ask is a fourth state, and the copy is not Eng…
emooreatx Aug 28, 2026
a69b45e
feat(portal): the surface is reachable, and two more fabricated answe…
emooreatx Aug 28, 2026
c5c026e
fix(portal): a verdict belongs to the node that gave it
emooreatx Aug 28, 2026
97a1d8e
feat(portal): match the server's declaration — null is not a missing key
emooreatx Aug 28, 2026
6e2ad9e
fix(portal): bind verification to the node actually selected
emooreatx Aug 29, 2026
41e5fa0
fix(portal): I traded a stale node for a wrong one
emooreatx Aug 29, 2026
7acd0e7
fix(i18n): stop stacking abstractions before saying anything
emooreatx Aug 29, 2026
096196b
fix(portal): a switch is an event, not an inequality
emooreatx Aug 29, 2026
36854aa
fix(i18n): do not put an undeclared term of art in front of 28 transl…
emooreatx Aug 29, 2026
96850b1
feat(capability): one reader for the wire contract, written to be quoted
emooreatx Aug 29, 2026
f3b12ad
fix(i18n): stop binning the whole lane because one pair came back clumsy
emooreatx Aug 29, 2026
59a37c4
i18n: translate lane (translate -> evaluate -> repair)
github-actions[bot] Aug 29, 2026
ea331df
i18n: translate lane (translate -> evaluate -> repair)
github-actions[bot] Aug 29, 2026
53ca3a3
fix(i18n): one name held two different things, and the lane crashed o…
emooreatx Aug 29, 2026
55b5c91
i18n: translate lane (translate -> evaluate -> repair)
github-actions[bot] Aug 29, 2026
9e18853
fix(i18n): the lane's push has to survive the branch moving under it
emooreatx Aug 29, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 30 additions & 3 deletions .github/workflows/i18n-lane.yml
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,10 @@ jobs:
path: i18n-report.json

- name: Guard (strict) — the actual gate
# always(), so a lane that exited 1 still gets its bundles checked and
# the operator sees BOTH facts: which keys were rejected, and what the
# structural gate says about what did land.
if: always()
# The pipeline proposes; this decides. Its own mutation self-test runs
# first, so the gate proves it can fail before it is trusted to pass.
run: |
Expand All @@ -146,7 +150,7 @@ jobs:
python3 client/tools/check_localization_sync.py --server-src .emitters --strict

- name: Re-record the vendoring state digest
if: inputs.commit
if: always() && inputs.commit
run: |
set -euo pipefail
DIGEST=$(python3 packaging/check_vendoring.py --print)
Expand All @@ -161,7 +165,14 @@ jobs:
python3 packaging/check_vendoring.py

- name: Commit
if: inputs.commit
env:
BRANCH: ${{ github.ref_name }}
# ALWAYS, even when the lane exited 1. The lane writes only ACCEPTED
# values now, so committing on failure banks the good work and leaves
# the rejected keys missing — which the strict guard then blocks on,
# exactly as it would have anyway. Skipping this on failure is what
# discarded 587 good translations per run, seven runs running.
if: always() && inputs.commit
run: |
set -euo pipefail
git config user.name "github-actions[bot]"
Expand All @@ -187,5 +198,21 @@ jobs:
The MQM findings are attached to the run as i18n-report.json.
Review like any other diff.
MSG
git push
# REBASE BEFORE PUSHING. The lane takes minutes and a human can
# land a commit on the same branch while it runs — which is exactly
# what happened: the runner committed the last translation, the push
# was rejected "fetch first", and the step failed AFTER doing all the
# work. Retry a few times because the race can recur.
for attempt in 1 2 3; do
if git push; then
exit 0
fi
echo "push rejected (attempt $attempt) — rebasing onto the branch and retrying"
git pull --rebase --autostash origin "$BRANCH" || true
# The bundles are regenerated deterministically from en.json, so a
# rebase conflict here means someone edited the same keys; let it
# fail loudly rather than resolving it blind.
done
echo "::error::could not push the translations after 3 attempts — the branch moved under the lane each time"
exit 1
fi
2 changes: 1 addition & 1 deletion client/VENDORING.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ source is the pair a bisect wants:
The tree's current recorded state — sha256-of-sha256s over every git-tracked
file under `client/` except this one:

**state digest:** `0ff13365d8b1b367cd9bc382f0b89e2bc51200dc0629ed93523b049020e147a8`
**state digest:** `c6c17a6c3a83b6d110a3b94fc6ac3aaf74ceb0c567000ad251048d1c82cf79a4`

`packaging/check_vendoring.py` asserts it on every push, and refuses any
tracked file matching a §2 never-vendor class. **Any commit that touches
Expand Down
21 changes: 21 additions & 0 deletions client/androidApp/src/main/assets/localization/am.json
Original file line number Diff line number Diff line change
Expand Up @@ -2924,6 +2924,27 @@
"wallet_transfer_success": "ማስተላለፍ ተሳክቷል! TX: {tx}",
"wallet_trust_degraded": "ስልክ ሥቅ ተዳክሞ ነበር",
"wallet_warning": "ማስጠንቀቂያ",
"verify_title": "ግንባታ ማረጋገጥ",
"verify_hash_label": "የግንባታ ሃሽ",
"verify_button": "አረጋግጥ",
"verify_undeclared_title": "ይህ ኖድ ግንባታዎችን እንደሚያረጋግጥ ወይም እንደማያረጋግጥ መናገር አይችልም",
"verify_undeclared_body": "ይህ ኖድ ከችሎታ መግለጫው የቀደመ ነው፤ ስለዚህ መናገር አይችልም። አዲስ ኖድ ግንባታዎችን ማረጋገጥ ይችላል።",
"verify_absent_title": "ይህ ኖድ ግንባታዎችን አያረጋግጥም",
"verify_absent_body": "ይህ ኖድ መዝገቡን አልያዘም፤ ስለዚህ ግንባታዎችን ማረጋገጥ አይችልም። ሌላ ኖድ ግን ይችላል።",
"verify_unreachable_title": "ወደዚህ ኖድ መድረስ አልተቻለም",
"verify_unreachable_body": "ኖዱ መልስ አልሰጠም፤ ስለዚህ ግንባታዎችን ማረጋገጥ እንደሚችል ወይም እንደማይችል አናውቅም። ይህ እርስዎ የሚያረጋግጡት ግንባታ ችግር አይደለም።",
"verify_status_registered": "ተመዝግቧል",
"verify_status_deprecated": "ከዚህ በኋላ አይመከርም",
"verify_status_revoked": "ተሰርዟል",
"verify_status_unreadable": "ሁኔታው አልታወቀም",
"verify_revoked_warning": "ይህ ግንባታ ተሰርዟል። አይጠቀሙበት።",
"verify_not_found_title": "ለዚህ ግንባታ ምንም መዝገብ የለም",
"verify_not_found_body": "መዝገቡ መልስ ሰጥቷል፤ ለዚህ ሃሽ ምንም አልያዘም።",
"verify_unavailable_title": "ማረጋገጥ አልተቻለም",
"verify_unavailable_body": "ይህ ‘አልተመዘገበም’ ከመባል ጋር አንድ አይደለም — መዝገቡ መልስ አልሰጠም።",
"verify_undetermined_title": "ይህ ኖድ ምን ማድረግ እንደሚችል መወሰን አልቻለም",
"verify_undetermined_body": "ኖዱ መልስ ሰጥቷል፣ ሆኖም የራሱን የቁልፍ መዝገብ ማንበብ አልቻለም። ይህ በተለምዶ ጊዜያዊ ነው — ከጥቂት ጊዜ በኋላ እንደገና ይሞክሩ።",
"verify_retry": "እንደገና አረጋግጥ",
"attestation_actions_desc": "ለዚህ መዝገብ ያሉ እርምጃዎች",
"chat_badge_message": "መልዕክት",
"chat_details": "ዓይነት {type} · ወሰን {scope} · ሁኔታ {status}",
Expand Down
21 changes: 21 additions & 0 deletions client/androidApp/src/main/assets/localization/ar.json
Original file line number Diff line number Diff line change
Expand Up @@ -2924,6 +2924,27 @@
"wallet_transfer_success": "نجح التحويل! TX: {tx}",
"wallet_trust_degraded": "تدهورت ثقة الأجهزة",
"wallet_warning": "تحذير",
"verify_title": "التحقق من إصدار",
"verify_hash_label": "بصمة الإصدار",
"verify_button": "تحقّق",
"verify_undeclared_title": "لا تستطيع هذه العقدة الإفادة عن قدرتها على التحقق من الإصدارات",
"verify_undeclared_body": "هذه العقدة أقدم من إعلان القدرات، فلا يمكنها الإفادة. عقدة أحدث تستطيع التحقق من الإصدارات.",
"verify_absent_title": "هذه العقدة لا تتحقق من الإصدارات",
"verify_absent_body": "لا تحمل هذه العقدة السجل، فلا يمكنها التحقق من الإصدارات. عقدة أخرى تستطيع ذلك.",
"verify_unreachable_title": "تعذّر الوصول إلى هذه العقدة",
"verify_unreachable_body": "لم تُجب العقدة، فلا نعرف أتستطيع التحقق من الإصدارات أم لا. وهذا ليس عطلاً في الإصدار الذي تتحقق منه.",
"verify_status_registered": "مسجَّل",
"verify_status_deprecated": "لم يعد يُنصح به",
"verify_status_revoked": "مُلغى",
"verify_status_unreadable": "الحالة غير معروفة",
"verify_revoked_warning": "هذا الإصدار أُلغي. لا تستخدمه.",
"verify_not_found_title": "لا سجل لهذا الإصدار",
"verify_not_found_body": "أجاب السجل ولا يحمل شيئاً لهذه البصمة.",
"verify_unavailable_title": "تعذّر التحقق",
"verify_unavailable_body": "هذا ليس كـ«غير مسجَّل» — فالسجل لم يُجب.",
"verify_undetermined_title": "تعذّر على هذه العقدة تحديد ما تستطيع فعله",
"verify_undetermined_body": "أجابت العقدة، لكنها لم تستطع قراءة سجل مفتاحها الخاص. هذا عادةً مؤقت — حاول مجدداً بعد قليل.",
"verify_retry": "تحقّق مجدداً",
"attestation_actions_desc": "إجراءات هذا السجل",
"chat_badge_message": "رسالة",
"chat_details": "النوع {type} · النطاق {scope} · الحالة {status}",
Expand Down
21 changes: 21 additions & 0 deletions client/androidApp/src/main/assets/localization/bn.json
Original file line number Diff line number Diff line change
Expand Up @@ -2925,6 +2925,27 @@
"wallet_transfer_success": "ট্রান্সফার সফল! TX: {tx}",
"wallet_trust_degraded": "হার্ডওয়্যার বিশ্বাস হ্রাস পেয়েছে",
"wallet_warning": "সতর্কতা",
"verify_title": "একটি বিল্ড যাচাই করুন",
"verify_hash_label": "বিল্ড হ্যাশ",
"verify_button": "পরীক্ষা করুন",
"verify_undeclared_title": "এই নোড বলতে পারে না যে এটি বিল্ড যাচাই করে কি না",
"verify_undeclared_body": "এই নোড সক্ষমতা ঘোষণার চেয়ে পুরনো, তাই এটি বলতে পারে না। নতুন কোনো নোড বিল্ড যাচাই করতে পারে।",
"verify_absent_title": "এই নোড বিল্ড যাচাই করে না",
"verify_absent_body": "এই নোড রেজিস্ট্রি ধারণ করে না, তাই এটি বিল্ড পরীক্ষা করতে পারে না। অন্য একটি নোড পারে।",
"verify_unreachable_title": "এই নোডে পৌঁছানো যায়নি",
"verify_unreachable_body": "নোডটি সাড়া দেয়নি, তাই এটি বিল্ড যাচাই করতে পারে কি না তা আমরা জানি না। আপনি যে বিল্ডটি পরীক্ষা করছেন তার সমস্যা এটি নয়।",
"verify_status_registered": "নিবন্ধিত",
"verify_status_deprecated": "আর প্রস্তাবিত নয়",
"verify_status_revoked": "প্রত্যাহৃত",
"verify_status_unreadable": "অবস্থা সনাক্ত করা যায়নি",
"verify_revoked_warning": "এই বিল্ডটি প্রত্যাহার করা হয়েছে। এটি ব্যবহার করবেন না।",
"verify_not_found_title": "এই বিল্ডের কোনো রেকর্ড নেই",
"verify_not_found_body": "রেজিস্ট্রি সাড়া দিয়েছে এবং এই হ্যাশের জন্য কিছুই ধারণ করে না।",
"verify_unavailable_title": "পরীক্ষা করা যায়নি",
"verify_unavailable_body": "এটি ‘নিবন্ধিত নয়’-এর সমান নয় — রেজিস্ট্রি সাড়া দেয়নি।",
"verify_undetermined_title": "এই নোড নির্ধারণ করতে পারেনি যে এটি কী করতে পারে",
"verify_undetermined_body": "নোডটি সাড়া দিয়েছে, কিন্তু নিজের কী রেকর্ড পড়তে পারেনি। এটি সাধারণত সাময়িক — কিছুক্ষণ পরে আবার চেষ্টা করুন।",
"verify_retry": "আবার পরীক্ষা করুন",
"attestation_actions_desc": "এই রেকর্ডের জন্য পদক্ষেপ",
"chat_badge_message": "বার্তা",
"chat_details": "ধরন {type} · পরিসর {scope} · অবস্থা {status}",
Expand Down
21 changes: 21 additions & 0 deletions client/androidApp/src/main/assets/localization/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -2862,6 +2862,20 @@
"users_status": "Status",
"users_user_id": "Benutzer-ID",
"users_wa_role": "WA:{role}",
"verify_unavailable_title": "Prüfung nicht möglich",
"verify_unavailable_body": "Das ist nicht dasselbe wie „nicht registriert“ — das Register hat nicht geantwortet.",
"verify_undetermined_title": "Dieser Knoten konnte nicht feststellen, was er kann",
"verify_undetermined_body": "Der Knoten hat geantwortet, konnte aber seinen eigenen Schlüsseldatensatz nicht lesen. Das ist meist vorübergehend — versuchen Sie es in Kürze erneut.",
"verify_retry": "Erneut prüfen",
"verify_unreachable_title": "Knoten nicht erreichbar",
"verify_unreachable_body": "Der Knoten hat nicht geantwortet, daher wissen wir nicht, ob er Builds verifizieren kann. Das liegt nicht an dem Build, den Sie prüfen.",
"verify_status_registered": "Registriert",
"verify_status_deprecated": "Nicht mehr empfohlen",
"verify_status_revoked": "Widerrufen",
"verify_status_unreadable": "Status nicht erkannt",
"verify_revoked_warning": "Dieser Build wurde widerrufen. Verwenden Sie ihn nicht.",
"verify_not_found_title": "Kein Eintrag für diesen Build",
"verify_not_found_body": "Das Register hat geantwortet und enthält nichts zu diesem Hash.",
"wa_approve": "Genehmigen",
"wa_avg_resolution": "Durchschnittl. Auflösung: {time} Min",
"wa_bus_subscribers": "Bus-Abonnenten",
Expand Down Expand Up @@ -2924,6 +2938,13 @@
"wallet_transfer_success": "Überweisung erfolgreich! TX: {tx}",
"wallet_trust_degraded": "Hardware-Vertrauen herabgestuft",
"wallet_warning": "Warnung",
"verify_title": "Build verifizieren",
"verify_hash_label": "Build-Hash",
"verify_button": "Prüfen",
"verify_undeclared_title": "Dieser Knoten kann nicht sagen, ob er Builds verifiziert",
"verify_undeclared_body": "Dieser Knoten ist älter als die Fähigkeitserklärung und kann daher keine Auskunft geben. Ein neuerer Knoten kann Builds verifizieren.",
"verify_absent_title": "Dieser Knoten verifiziert keine Builds",
"verify_absent_body": "Dieser Knoten verwaltet das Register nicht und kann daher keine Builds prüfen. Ein anderer Knoten kann das.",
"attestation_actions_desc": "Aktionen für diesen Datensatz",
"chat_badge_message": "NACHRICHT",
"chat_details": "Typ {type} · Bereich {scope} · Status {status}",
Expand Down
23 changes: 22 additions & 1 deletion client/androidApp/src/main/assets/localization/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -2993,7 +2993,28 @@
"wallet_transfer_note": "Transfer to another Base address for fiat cashout",
"wallet_transfer_success": "Transfer successful! TX: {tx}",
"wallet_trust_degraded": "Hardware Trust Degraded",
"wallet_warning": "Warning"
"wallet_warning": "Warning",
"verify_title": "Verify a build",
"verify_hash_label": "Build hash",
"verify_button": "Check",
"verify_undeclared_title": "This node cannot say whether it verifies builds",
"verify_undeclared_body": "This node is older than the capability declaration, so it cannot say. A newer node can verify builds.",
"verify_absent_title": "This node does not verify builds",
"verify_absent_body": "This node does not carry the registry, so it cannot check builds. Another node can.",
"verify_unreachable_title": "Could not reach this node",
"verify_unreachable_body": "The node did not answer, so we do not know whether it can verify builds. This is not a problem with the build you are checking.",
"verify_status_registered": "Registered",
"verify_status_deprecated": "No longer recommended",
"verify_status_revoked": "Revoked",
"verify_status_unreadable": "Status not recognised",
"verify_revoked_warning": "This build has been revoked. Do not use it.",
"verify_not_found_title": "No record of this build",
"verify_not_found_body": "The registry answered and holds nothing for this hash.",
"verify_unavailable_title": "Could not check",
"verify_unavailable_body": "This is not the same as 'not registered' — the registry did not answer.",
"verify_undetermined_title": "This node could not determine what it can do",
"verify_undetermined_body": "The node answered, but could not read its own key record. This is usually temporary — try again shortly.",
"verify_retry": "Check again"
},
"moderation": {
"ladder": {
Expand Down
21 changes: 21 additions & 0 deletions client/androidApp/src/main/assets/localization/es.json
Original file line number Diff line number Diff line change
Expand Up @@ -2924,6 +2924,27 @@
"wallet_transfer_success": "¡Transferencia exitosa! TX: {tx}",
"wallet_trust_degraded": "Confianza de Hardware Degradada",
"wallet_warning": "Advertencia",
"verify_title": "Verificar una compilación",
"verify_hash_label": "Hash de la compilación",
"verify_button": "Comprobar",
"verify_undeclared_title": "Este nodo no puede decir si verifica compilaciones",
"verify_undeclared_body": "Este nodo es anterior a la declaración de capacidades, así que no puede saberlo. Un nodo más reciente puede verificar compilaciones.",
"verify_absent_title": "Este nodo no verifica compilaciones",
"verify_absent_body": "Este nodo no aloja el registro, así que no puede comprobar compilaciones. Otro nodo sí puede.",
"verify_unreachable_title": "No se pudo contactar con este nodo",
"verify_unreachable_body": "El nodo no respondió, así que no sabemos si puede verificar compilaciones. Esto no es un problema de la compilación que estás comprobando.",
"verify_status_registered": "Registrada",
"verify_status_deprecated": "Ya no se recomienda",
"verify_status_revoked": "Revocada",
"verify_status_unreadable": "Estado no reconocido",
"verify_revoked_warning": "Esta compilación ha sido revocada. No la uses.",
"verify_not_found_title": "No hay registro de esta compilación",
"verify_not_found_body": "El registro respondió y no tiene nada para este hash.",
"verify_unavailable_title": "No se pudo comprobar",
"verify_unavailable_body": "Esto no es lo mismo que «no registrada» — el registro no respondió.",
"verify_undetermined_title": "Este nodo no pudo determinar qué puede hacer",
"verify_undetermined_body": "El nodo respondió, pero no pudo leer su propio registro de claves. Esto suele ser temporal — inténtalo de nuevo en breve.",
"verify_retry": "Comprobar de nuevo",
"attestation_actions_desc": "Acciones para este registro",
"chat_badge_message": "MENSAJE",
"chat_details": "tipo {type} · ámbito {scope} · estado {status}",
Expand Down
Loading
Loading