Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
322 changes: 322 additions & 0 deletions .eamos-core/orchestrator/os/localization/labels.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,322 @@
# Chrome labels (RFC-0001 §7, #61) — every rendered chrome string, per language, as DATA.
# The single source of truth replacing eight duplicated in-code tables: adding a language is a
# one-file edit here, never a code change. `en` is the declared fallback. A language is supported
# only when it defines EVERY key (half-localized is worse than honestly unsupported) — enforced by
# the labels-valid gate. Namespaces preserve intentional per-deliverable differences (the .docx
# uses title-case, the sheet says "Source / note"), so values must not be merged across them.
#
# core.verify — the suffix inside the ⟨value — …⟩ grounding marker (RFC-0001 §6)
# core.redacted — the word inside the ⟦…⟧ egress-redaction mask (RFC-0001 §11)
version: 1

en:
core:
verify: "to verify"
redacted: "redacted"
quiz_stem: "What is the value of"
quiz_disc: "What is the stance on"
md:
target: "target"
risk: "Risk"
ask: "Ask"
decision: "Decision"
review: "Verify before the room"
objective: "Objective"
fill: "source"
pro: "pro"
con: "con"
next_step: "Next step"
residual_risk: "Residual risk"
quiz_md:
title: "Interview quiz"
graded: "Graded (citation required)"
disc: "Discussion (un-scored)"
ans: "Answer"
src: "source"
verify: "to verify"
pptx:
target: "target"
risk: "Risk"
ask: "Ask"
pro: "pro"
con: "con"
review: "Verify before the room"
fill: "source"
next_step: "Next step"
residual_risk: "Residual risk"
docx:
target: "Target"
value: "Value"
kpi: "KPI"
risk: "Risk"
ask: "Ask"
pro: "pro"
con: "con"
review: "Verify before the room"
fill: "source"
preread: "Pre-read"
next_step: "Next step"
residual_risk: "Residual risk"
svg:
decisions: "Decisions required"
target: "target"
verify: "to verify"
xlsx:
kpi: "KPI"
value: "Value"
target: "Target"
source: "Source / note"
review: "Verify before the room"
facilitate:
agenda: "Agenda"
script: "Facilitation script"
min: "min"
obj: "Objective"
talk: "Talking points"
minutes: "Minutes"
decisions: "Decisions"
actions: "Action items"
owner: "owner"
due: "due"
notes: "Notes"
attendees: "Attendees"
joins_at: "joins at"
input_gathering: "Input gathering"
live_classification: "Live classification"
targeted_questions: "Targeted questions"
structured_synthesis: "Structured synthesis"
decision_framing: "Decision framing"

it:
core:
verify: "da verificare"
redacted: "redatto"
quiz_stem: "Qual è il valore di"
quiz_disc: "Qual è la posizione su"
md:
target: "target"
risk: "Rischio"
ask: "Richiesta"
decision: "Decisione"
review: "Da verificare prima della sala"
objective: "Obiettivo"
fill: "fonte"
pro: "pro"
con: "contro"
next_step: "Prossimo passo"
residual_risk: "Rischio residuo"
quiz_md:
title: "Quiz d'intervista"
graded: "Valutate (citazione richiesta)"
disc: "Discussione (non valutate)"
ans: "Risposta"
src: "fonte"
verify: "da verificare"
pptx:
target: "target"
risk: "Rischio"
ask: "Richiesta"
pro: "pro"
con: "contro"
review: "Da verificare prima della sala"
fill: "fonte"
next_step: "Prossimo passo"
residual_risk: "Rischio residuo"
docx:
target: "Target"
value: "Valore"
kpi: "KPI"
risk: "Rischio"
ask: "Richiesta"
pro: "pro"
con: "contro"
review: "Da verificare prima della sala"
fill: "fonte"
preread: "Pre-read"
next_step: "Prossimo passo"
residual_risk: "Rischio residuo"
svg:
decisions: "Decisioni richieste"
target: "target"
verify: "valori da verificare"
xlsx:
kpi: "KPI"
value: "Valore"
target: "Target"
source: "Fonte / nota"
review: "Da verificare prima della sala"
facilitate:
agenda: "Agenda"
script: "Script di facilitazione"
min: "min"
obj: "Obiettivo"
talk: "Punti da toccare"
minutes: "Verbale"
decisions: "Decisioni"
actions: "Azioni"
owner: "owner"
due: "scadenza"
notes: "Note"
attendees: "Partecipanti"
joins_at: "entra da"
input_gathering: "Raccolta input"
live_classification: "Classificazione dal vivo"
targeted_questions: "Domande mirate"
structured_synthesis: "Sintesi strutturata"
decision_framing: "Inquadramento decisione"

es:
core:
verify: "por verificar"
redacted: "redactado"
quiz_stem: "¿Cuál es el valor de"
quiz_disc: "¿Cuál es la posición sobre"
md:
target: "meta"
risk: "Riesgo"
ask: "Solicitud"
decision: "Decisión"
review: "Verificar antes de la reunión"
objective: "Objetivo"
fill: "fuente"
pro: "pro"
con: "contra"
next_step: "Próximo paso"
residual_risk: "Riesgo residual"
quiz_md:
title: "Cuestionario de entrevista"
graded: "Evaluadas (cita requerida)"
disc: "Discusión (sin puntuar)"
ans: "Respuesta"
src: "fuente"
verify: "por verificar"
pptx:
target: "meta"
risk: "Riesgo"
ask: "Solicitud"
pro: "pro"
con: "contra"
review: "Verificar antes de la reunión"
fill: "fuente"
next_step: "Próximo paso"
residual_risk: "Riesgo residual"
docx:
target: "Meta"
value: "Valor"
kpi: "KPI"
risk: "Riesgo"
ask: "Solicitud"
pro: "pro"
con: "contra"
review: "Verificar antes de la reunión"
fill: "fuente"
preread: "Prelectura"
next_step: "Próximo paso"
residual_risk: "Riesgo residual"
svg:
decisions: "Decisiones requeridas"
target: "meta"
verify: "valores por verificar"
xlsx:
kpi: "KPI"
value: "Valor"
target: "Meta"
source: "Fuente / nota"
review: "Verificar antes de la reunión"
facilitate:
agenda: "Agenda"
script: "Guion de facilitación"
min: "min"
obj: "Objetivo"
talk: "Puntos a tratar"
minutes: "Acta"
decisions: "Decisiones"
actions: "Acciones"
owner: "responsable"
due: "vencimiento"
notes: "Notas"
attendees: "Participantes"
joins_at: "se une desde"
input_gathering: "Recogida de datos"
live_classification: "Clasificación en vivo"
targeted_questions: "Preguntas dirigidas"
structured_synthesis: "Síntesis estructurada"
decision_framing: "Encuadre de la decisión"

fr:
core:
verify: "à vérifier"
redacted: "caviardé"
quiz_stem: "Quelle est la valeur de"
quiz_disc: "Quelle est la position sur"
md:
target: "cible"
risk: "Risque"
ask: "Demande"
decision: "Décision"
review: "À vérifier avant la réunion"
objective: "Objectif"
fill: "source"
pro: "pour"
con: "contre"
next_step: "Prochaine étape"
residual_risk: "Risque résiduel"
quiz_md:
title: "Quiz d'entretien"
graded: "Notées (citation requise)"
disc: "Discussion (non notées)"
ans: "Réponse"
src: "source"
verify: "à vérifier"
pptx:
target: "cible"
risk: "Risque"
ask: "Demande"
pro: "pour"
con: "contre"
review: "À vérifier avant la réunion"
fill: "source"
next_step: "Prochaine étape"
residual_risk: "Risque résiduel"
docx:
target: "Cible"
value: "Valeur"
kpi: "KPI"
risk: "Risque"
ask: "Demande"
pro: "pour"
con: "contre"
review: "À vérifier avant la réunion"
fill: "source"
preread: "Pré-lecture"
next_step: "Prochaine étape"
residual_risk: "Risque résiduel"
svg:
decisions: "Décisions requises"
target: "cible"
verify: "valeurs à vérifier"
xlsx:
kpi: "KPI"
value: "Valeur"
target: "Cible"
source: "Source / note"
review: "À vérifier avant la réunion"
facilitate:
agenda: "Ordre du jour"
script: "Script de facilitation"
min: "min"
obj: "Objectif"
talk: "Points à aborder"
minutes: "Compte rendu"
decisions: "Décisions"
actions: "Actions"
owner: "responsable"
due: "échéance"
notes: "Notes"
attendees: "Participants"
joins_at: "rejoint à"
input_gathering: "Recueil des données"
live_classification: "Classification en direct"
targeted_questions: "Questions ciblées"
structured_synthesis: "Synthèse structurée"
decision_framing: "Cadrage de la décision"
30 changes: 30 additions & 0 deletions .eamos-core/tools/eamos_lint.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
classification-valid — a problem-type classification (if present) uses taxonomy-allowed values.
questions-valid — the adaptive question tree + routing stay consistent with the taxonomy.
topology-valid — a topology diagram's edges/kinds/patterns are declared and in-vocabulary.
labels-valid — every language in os/localization/labels.yaml defines every chrome key
the en fallback defines (a language is supported when ALL chrome exists).
"""

import os
Expand All @@ -36,6 +38,7 @@
TOOLS = os.path.dirname(os.path.abspath(__file__))
sys.path.insert(0, TOOLS)
import _cli # noqa: E402 (utf8_stdio, #54)
import labels # noqa: E402 (chrome labels as data, #61)
import render # noqa: E402 (reuses the loader + build_deck_ir)
import yamlmini # noqa: E402

Expand Down Expand Up @@ -275,6 +278,32 @@ def gate_topology_valid(manifest):
return findings


def gate_labels_valid():
"""Chrome-label completeness (#61): every language in os/localization/labels.yaml defines every
key the `en` fallback defines, and nothing more — a language is supported when ALL chrome exists
(half-localized is worse than honestly unsupported), and a key unknown to the fallback is drift.
Structural + decidable, manifest-independent; vacuous if the file is absent."""
findings = []
data = labels.load()
ref = data.get(labels.FALLBACK) or {}
if not ref:
return findings
for lang, tables in sorted(data.items()):
if lang == labels.FALLBACK or not isinstance(tables, dict):
continue # skip the reference itself + scalars (version)
for ns, keys in sorted(ref.items()):
have = tables.get(ns) or {}
for k in sorted(keys):
if k not in have:
findings.append(("labels-valid", f"language '{lang}' is missing label '{ns}.{k}'"))
for ns, keys in sorted(tables.items()):
for k in sorted(keys or {}):
if k not in (ref.get(ns) or {}):
findings.append(("labels-valid",
f"label '{ns}.{k}' in '{lang}' is not defined by the '{labels.FALLBACK}' fallback"))
return findings


def gate_registry_params(manifest):
"""Every deliverable's params are within the registry's declared enums (RFC-0002 §4)."""
findings = []
Expand Down Expand Up @@ -365,6 +394,7 @@ def run_all(manifest, archetype, deck_ir, acc, ledger):
findings += gate_classification_valid(manifest)
findings += gate_questions_valid()
findings += gate_topology_valid(manifest)
findings += gate_labels_valid()
findings += gate_registry_params(manifest)
findings += gate_rubric(manifest, deck_ir, {g for g, _ in findings})
findings += gate_confidentiality(manifest, {g for g, _ in findings})
Expand Down
Loading
Loading