Merge pull request #135 from Xahau/main

Roadmap update
This commit is contained in:
Ekiserrepé
2026-08-14 11:04:04 +02:00
committed by GitHub
3 changed files with 210 additions and 125 deletions

View File

@@ -45,6 +45,35 @@ const tr = (v: unknown): string => {
return ''
}
/**
* Card tag text.
*
* Items carry vocabulary *keys* (`phase`, `note`) rather than per-locale
* strings, so a wording change happens once in `labels.<locale>.tags` instead
* of once per item per language. Renders "<phase> · <note>"; `note` is
* optional. `tag` stays supported as a free-form escape hatch for one-offs.
*
* An unknown key is a build error, not a silently blank tag — the fallback
* locale is checked too, so a key missing only from a translation still
* renders (in the default locale) rather than breaking the page.
*/
const tagFor = (it: RoadmapItem): string => {
if (!it.phase) return it.tag ? tr(it.tag) : ''
const pick = (kind: 'phases' | 'notes', key: string): string => {
const here = data.labels[lang]?.tags?.[kind]?.[key]
const base = data.labels[defaultLocale]?.tags?.[kind]?.[key]
if (here ?? base) return (here ?? base) as string
throw new Error(
`roadmap.json: item "${it.id}" uses ${kind === 'phases' ? 'phase' : 'note'} ` +
`"${key}", which is not defined in labels.${defaultLocale}.tags.${kind}.`,
)
}
const phase = pick('phases', it.phase)
return it.note ? `${phase} · ${pick('notes', it.note)}` : phase
}
const qToIdx = (q: string) => {
const [y, qx] = q.split('-Q')
return Number(y) * 4 + (Number(qx) - 1)
@@ -209,7 +238,7 @@ const fmtItemPeriod = (item: RoadmapItem): string => {
return (
<article class={classes} style={`grid-column:${p.col} / span ${p.span};`}>
<span class="xr-q-badge" aria-hidden="true">{fmtItemPeriod(it)}</span>
{it.tag && <div class="k">{tr(it.tag)}</div>}
{tagFor(it) && <div class="k">{tagFor(it)}</div>}
<div class="n">{tr(it.title)}</div>
{it.description && <div class="d">{tr(it.description)}</div>}
<span class="peg" aria-hidden="true"></span>
@@ -245,7 +274,7 @@ const fmtItemPeriod = (item: RoadmapItem): string => {
<article class={classes} style={`grid-column:${p.col} / span ${p.span};`}>
<span class="peg" aria-hidden="true"></span>
<span class="xr-q-badge" aria-hidden="true">{fmtItemPeriod(it)}</span>
{it.tag && <div class="k">{tr(it.tag)}</div>}
{tagFor(it) && <div class="k">{tagFor(it)}</div>}
<div class="n">{tr(it.title)}</div>
{it.description && <div class="d">{tr(it.description)}</div>}
</article>

View File

@@ -1,6 +1,5 @@
{
"$comment": "Xahau roadmap source of truth. Edit this file to add/update/remove items. Committed JSON is rendered at build time by src/components/XahauRoadmap.astro — no runtime JS required.",
"$comment": "Xahau roadmap source of truth. Edit this file to add/update/remove items. Committed JSON is rendered at build time by src/components/XahauRoadmap.astro — no runtime JS required. Card tags come from `labels.<locale>.tags`: set `phase` (and optionally `note`) on an item instead of writing the tag text per locale.",
"meta": {
"updated": "2026-04-19",
"window": {
@@ -14,7 +13,6 @@
"locales": ["en", "es", "pt-BR"]
}
},
"labels": {
"en": {
"title": "Xahau Roadmap",
@@ -54,6 +52,33 @@
"partnership": "Partnership",
"launch": "Launch / public good"
},
"tags": {
"$comment": "Card tag vocabulary. Items reference these by key via `phase` / `note`; the card renders \"<phase> · <note>\". Edit a word here and it changes everywhere it is used. A `note` is written to agree with the `phase` it follows (gender/number), so check before reusing one under a new phase.",
"phases": {
"feature": "Feature",
"ongoing": "Ongoing",
"live": "Live",
"ga": "GA",
"pilot": "Pilot",
"launch": "Launch",
"partnerships": "Partnerships",
"enterprise": "Enterprise",
"event": "Event"
},
"notes": {
"activated": "Activated",
"ready-for-amendment": "ready for amendment",
"in-development": "in development",
"alpha": "in alpha development",
"beta": "in beta development",
"audits-optimisations": "audits + optimisations",
"remittance": "remittance",
"payments": "payments",
"public-good": "public good",
"quarterly": "quarterly",
"enterprise-devs": "enterprise + devs"
}
},
"foot": "Directional - subject to change - xahau.network"
},
"es": {
@@ -94,6 +119,33 @@
"partnership": "Alianza",
"launch": "Lanzamiento / bien público"
},
"tags": {
"$comment": "Card tag vocabulary. Items reference these by key via `phase` / `note`; the card renders \"<phase> · <note>\". Edit a word here and it changes everywhere it is used. A `note` is written to agree with the `phase` it follows (gender/number), so check before reusing one under a new phase.",
"phases": {
"feature": "Función",
"ongoing": "Continuo",
"live": "En vivo",
"ga": "GA",
"pilot": "Piloto",
"launch": "Lanzamiento",
"partnerships": "Alianzas",
"enterprise": "Empresarial",
"event": "Evento"
},
"notes": {
"activated": "activada",
"ready-for-amendment": "lista para enmienda",
"in-development": "en desarrollo",
"alpha": "en desarrollo alfa",
"beta": "en desarrollo beta",
"audits-optimisations": "auditorías y optimizaciones",
"remittance": "remesas",
"payments": "pagos",
"public-good": "bien público",
"quarterly": "trimestral",
"enterprise-devs": "empresas y desarrolladores"
}
},
"foot": "Orientativo - sujeto a cambios - xahau.network"
},
"pt-BR": {
@@ -134,22 +186,83 @@
"partnership": "Parceria",
"launch": "Lançamento / bem público"
},
"tags": {
"$comment": "Card tag vocabulary. Items reference these by key via `phase` / `note`; the card renders \"<phase> · <note>\". Edit a word here and it changes everywhere it is used. A `note` is written to agree with the `phase` it follows (gender/number), so check before reusing one under a new phase.",
"phases": {
"feature": "Funcionalidade",
"ongoing": "Contínuo",
"live": "Ao vivo",
"ga": "GA",
"pilot": "Piloto",
"launch": "Lançamento",
"partnerships": "Parcerias",
"enterprise": "Empresarial",
"event": "Evento"
},
"notes": {
"activated": "ativada",
"ready-for-amendment": "pronta para emenda",
"in-development": "em desenvolvimento",
"alpha": "em desenvolvimento alfa",
"beta": "em desenvolvimento beta",
"audits-optimisations": "auditorias e otimizações",
"remittance": "remessas",
"payments": "pagamentos",
"public-good": "bem público",
"quarterly": "trimestral",
"enterprise-devs": "empresas e desenvolvedores"
}
},
"foot": "Direcional - sujeito a alterações - xahau.network"
}
},
"items": [
{
"id": "price-oracle",
"lane": "tech",
"status": "feature",
"quarter": "2026-Q2",
"span": 2,
"phase": "feature",
"note": "activated",
"title": {
"en": "PriceOracle",
"es": "PriceOracle",
"pt-BR": "PriceOracle"
},
"description": {
"en": "Native on-ledger price feed primitive — tamper-resistant asset prices for DeFi, AMM and Hooks.",
"es": "Primitiva nativa de precios en el ledger — precios de activos resistentes a manipulación para DeFi, AMM y Hooks.",
"pt-BR": "Primitiva nativa de feed de preços no ledger — preços de ativos resistentes a adulterações para DeFi, AMM e Hooks."
}
},
{
"id": "iou-reward-claim",
"lane": "tech",
"status": "feature",
"quarter": "2026-Q2",
"endQuarter": "2026-Q3",
"phase": "feature",
"note": "activated",
"title": {
"en": "IOURewardClaim",
"es": "IOURewardClaim",
"pt-BR": "IOURewardClaim"
},
"description": {
"en": "Extends the current RewardClaim for XAH to make it available for IOU tokens as well — letting projects use Hooks to distribute rewards based on a user's token holdings.",
"es": "Extiende el RewardClaim actual de XAH para ofrecerlo también a tokens IOU — permitiendo a los proyectos usar Hooks para distribuir recompensas según las tenencias de tokens de un usuario.",
"pt-BR": "Estende o RewardClaim atual do XAH para torná-lo disponível também para tokens IOU — permitindo que projetos usem Hooks para distribuir recompensas com base nas posições de tokens de um usuário."
}
},
{
"id": "rng",
"lane": "tech",
"status": "feature",
"quarter": "2026-Q2",
"endQuarter": "2026-Q2",
"tag": {
"en": "Feature · in beta development",
"es": "Función · en desarrollo beta",
"pt-BR": "Funcionalidade · em desenvolvimento beta"
},
"endQuarter": "2026-Q3",
"phase": "feature",
"note": "beta",
"title": {
"en": "Random Number Generator",
"es": "Generador de números aleatorios",
@@ -167,11 +280,8 @@
"status": "feature",
"quarter": "2026-Q2",
"endQuarter": "2026-Q3",
"tag": {
"en": "Feature · in development",
"es": "Función · en desarrollo",
"pt-BR": "Funcionalidade · em desenvolvimento"
},
"phase": "feature",
"note": "in-development",
"title": {
"en": "FeatureExport",
"es": "FeatureExport",
@@ -189,74 +299,32 @@
"status": "feature",
"quarter": "2026-Q2",
"span": 2,
"tag": {
"en": "Feature · ready for amendment",
"es": "Función · lista para enmienda",
"pt-BR": "Funcionalidade · pronta para emenda"
"phase": "feature",
"note": "ready-for-amendment",
"title": {
"en": "AMM",
"es": "AMM",
"pt-BR": "AMM"
},
"title": { "en": "AMM", "es": "AMM", "pt-BR": "AMM" },
"description": {
"en": "Automated Market Maker primitive for deep native liquidity on the Xahau DEX. Merged into the xahaud dev branch, awaiting amendment vote.",
"es": "Primitiva Automated Market Maker para liquidez nativa profunda en el DEX de Xahau. Integrada en la rama dev de xahaud, a la espera de la votación de enmienda.",
"pt-BR": "Primitiva de Automated Market Maker para liquidez nativa profunda no DEX da Xahau. Integrada ao branch dev do xahaud, aguardando votação de emenda."
}
},
{
"id": "price-oracle",
"lane": "tech",
"status": "feature",
"quarter": "2026-Q2",
"span": 2,
"tag": {
"en": "Feature · ready for amendment",
"es": "Función · lista para enmienda",
"pt-BR": "Funcionalidade · pronta para emenda"
},
"title": {
"en": "PriceOracle",
"es": "PriceOracle",
"pt-BR": "PriceOracle"
},
"description": {
"en": "Native on-ledger price feed primitive — tamper-resistant asset prices for DeFi, AMM and Hooks. Merged into the xahaud dev branch, awaiting amendment vote.",
"es": "Primitiva nativa de precios en el ledger — precios de activos resistentes a manipulación para DeFi, AMM y Hooks. Integrada en la rama dev de xahaud, a la espera de la votación de enmienda.",
"pt-BR": "Primitiva nativa de feed de preços no ledger — preços de ativos resistentes a adulterações para DeFi, AMM e Hooks. Integrada ao branch dev do xahaud, aguardando votação de emenda."
}
},
{
"id": "iou-reward-claim",
"lane": "tech",
"status": "feature",
"quarter": "2026-Q2",
"endQuarter": "2026-Q3",
"tag": {
"en": "Feature · in development",
"es": "Función · en desarrollo",
"pt-BR": "Funcionalidade · em desenvolvimento"
},
"title": {
"en": "IOURewardClaim",
"es": "IOURewardClaim",
"pt-BR": "IOURewardClaim"
},
"description": {
"en": "Extends the current RewardClaim for XAH to make it available for IOU tokens as well — letting projects use Hooks to distribute rewards based on a user's token holdings.",
"es": "Extiende el RewardClaim actual de XAH para ofrecerlo también a tokens IOU — permitiendo a los proyectos usar Hooks para distribuir recompensas según las tenencias de tokens de un usuario.",
"pt-BR": "Estende o RewardClaim atual do XAH para torná-lo disponível também para tokens IOU — permitindo que projetos usem Hooks para distribuir recompensas com base nas posições de tokens de um usuário."
}
},
{
"id": "named-hook",
"lane": "tech",
"status": "feature",
"quarter": "2026-Q3",
"endQuarter": "2026-Q4",
"tag": {
"en": "Feature · in development",
"es": "Función · en desarrollo",
"pt-BR": "Funcionalidade · em desenvolvimento"
"phase": "feature",
"note": "ready-for-amendment",
"title": {
"en": "NamedHook",
"es": "NamedHook",
"pt-BR": "NamedHook"
},
"title": { "en": "NamedHook", "es": "NamedHook", "pt-BR": "NamedHook" },
"description": {
"en": "Allows names to be set to identify Hooks, so different Hooks can be invoked even within the same transaction type.",
"es": "Permite asignar nombres para identificar Hooks, de modo que se puedan invocar diferentes Hooks incluso dentro del mismo tipo de transacción.",
@@ -269,12 +337,13 @@
"status": "feature",
"quarter": "2026-Q2",
"span": 3,
"tag": {
"en": "Feature · in alpha development",
"es": "Función · en desarrollo alfa",
"pt-BR": "Funcionalidade · em desenvolvimento alfa"
"phase": "feature",
"note": "alpha",
"title": {
"en": "JSHooks",
"es": "JSHooks",
"pt-BR": "JSHooks"
},
"title": { "en": "JSHooks", "es": "JSHooks", "pt-BR": "JSHooks" },
"description": {
"en": "JavaScript runtime for Hooks — write Xahau smart-contract logic in JavaScript alongside the existing WebAssembly runtime, broadening the developer surface.",
"es": "Entorno de ejecución JavaScript para Hooks — escribir la lógica de smart contracts en JavaScript junto al entorno WebAssembly existente, ampliando la superficie para desarrolladores.",
@@ -287,11 +356,8 @@
"status": "feature",
"quarter": "2026-Q2",
"openEnded": true,
"tag": {
"en": "Ongoing · audits + optimisations",
"es": "Continuo · auditorías y optimizaciones",
"pt-BR": "Contínuo · auditorias e otimizações"
},
"phase": "ongoing",
"note": "audits-optimisations",
"title": {
"en": "Audit & optimisations",
"es": "Auditorías y optimizaciones",
@@ -303,19 +369,15 @@
"pt-BR": "Auditorias de segurança e melhorias de desempenho contínuas no protocolo, Hooks e ferramentas."
}
},
{
"id": "coopbank-eur",
"lane": "rollout",
"status": "live",
"quarter": "2026-Q2",
"openEnded": false,
"span": 2,
"tag": {
"en": "Live · remittance",
"es": "En vivo · remesas",
"pt-BR": "Ao vivo · remessas"
},
"openEnded": false,
"phase": "live",
"note": "remittance",
"title": {
"en": "COOP Bank EUR corridor scale-up to entire country.",
"es": "Escalado del corredor EUR de COOP Bank a todo el país.",
@@ -333,7 +395,7 @@
"status": "partnership",
"quarter": "2026-Q2",
"endQuarter": "2026-Q3",
"tag": { "en": "Launch", "es": "Lanzamiento", "pt-BR": "Lançamento" },
"phase": "launch",
"title": {
"en": "USD stablecoin on Xahau",
"es": "Stablecoin USD en Xahau",
@@ -351,7 +413,7 @@
"status": "partnership",
"quarter": "2026-Q4",
"openEnded": true,
"tag": { "en": "Launch", "es": "Lanzamiento", "pt-BR": "Lançamento" },
"phase": "launch",
"title": {
"en": "Currencies from multiple countries on Xahau",
"es": "Divisas de múltiples países en Xahau",
@@ -369,7 +431,7 @@
"status": "partnership",
"quarter": "2026-Q3",
"endQuarter": "2026-Q4",
"tag": { "en": "Launch", "es": "Lanzamiento", "pt-BR": "Lançamento" },
"phase": "launch",
"title": {
"en": "GBP stablecoin on Xahau",
"es": "Stablecoin GBP en Xahau",
@@ -387,7 +449,7 @@
"status": "pilot",
"quarter": "2026-Q3",
"endQuarter": "2026-Q4",
"tag": { "en": "Pilot", "es": "Piloto", "pt-BR": "Piloto" },
"phase": "pilot",
"title": {
"en": "USD corridor pilot",
"es": "Piloto del corredor USD",
@@ -405,7 +467,7 @@
"status": "partnership",
"quarter": "2026-Q4",
"openEnded": true,
"tag": { "en": "Partnerships", "es": "Alianzas", "pt-BR": "Parcerias" },
"phase": "partnerships",
"title": {
"en": "Additional bank & remittance partners",
"es": "Bancos y socios de remesas adicionales",
@@ -423,11 +485,8 @@
"status": "live",
"quarter": "2027-Q1",
"span": 1,
"tag": {
"en": "GA · remittance",
"es": "GA · remesas",
"pt-BR": "GA · remessas"
},
"phase": "ga",
"note": "remittance",
"title": {
"en": "Corridor expansion · GA",
"es": "Expansión de corredores · GA",
@@ -445,11 +504,8 @@
"status": "pilot",
"quarter": "2027-Q2",
"endQuarter": "2027-Q3",
"tag": {
"en": "Pilot · payments",
"es": "Piloto · pagos",
"pt-BR": "Piloto · pagamentos"
},
"phase": "pilot",
"note": "payments",
"title": {
"en": "Merchant settlement pilot",
"es": "Piloto de liquidación para comercios",
@@ -461,18 +517,13 @@
"pt-BR": "Liquidação com stablecoins e conformidade baseada em Hooks para comerciantes."
}
},
{
"id": "enterprise-ga",
"lane": "rollout",
"status": "partnership",
"quarter": "2027-Q3",
"openEnded": true,
"tag": {
"en": "Enterprise",
"es": "Empresarial",
"pt-BR": "Empresarial"
},
"phase": "enterprise",
"title": {
"en": "Enterprise settlement GA",
"es": "GA de liquidación empresarial",
@@ -484,18 +535,14 @@
"pt-BR": "Oferta de produção para parceiros regulamentados, construída sobre componentes Hooks auditados."
}
},
{
"id": "ngo-donations",
"lane": "rollout",
"status": "launch",
"quarter": "2026-Q4",
"openEnded": true,
"tag": {
"en": "Launch · public good",
"es": "Lanzamiento · bien público",
"pt-BR": "Lançamento · bem público"
},
"phase": "launch",
"note": "public-good",
"title": {
"en": "NGO donation platform",
"es": "Plataforma de donaciones para ONG",
@@ -535,11 +582,8 @@
"status": "launch",
"quarter": "2026-Q2",
"openEnded": true,
"tag": {
"en": "Event · quarterly",
"es": "Evento · trimestral",
"pt-BR": "Evento · trimestral"
},
"phase": "event",
"note": "quarterly",
"title": {
"en": "Xahau Connect",
"es": "Xahau Connect",
@@ -556,11 +600,8 @@
"lane": "rollout",
"status": "launch",
"quarter": "2026-Q4",
"tag": {
"en": "Event · enterprise + devs",
"es": "Evento · empresas y desarrolladores",
"pt-BR": "Evento · empresas e desenvolvedores"
},
"phase": "event",
"note": "enterprise-devs",
"title": {
"en": "InFTF event",
"es": "Evento InFTF",

View File

@@ -29,6 +29,14 @@ export const roadmapItem = z.object({
// Ongoing activity with no firm end date. Stretches to the end of the visible
// window and renders a "continues" indicator. Overrides `span`/`endQuarter`.
openEnded: z.boolean().optional().default(false),
// Card tag, built from the shared vocabulary in `labels.<locale>.tags`.
// `phase` is the base word ('feature' -> "Feature"), `note` the optional
// qualifier ('activated' -> "Activated"); the card renders "phase · note".
// Both are keys, not text — translations live in `labels`, not on the item.
phase: z.string().min(1).optional(),
note: z.string().min(1).optional(),
// Escape hatch for one-off tags that aren't part of the vocabulary.
// Ignored when `phase` is set. Prefer `phase`/`note` for anything reusable.
tag: localized.optional(),
title: localized,
description: localized.optional(),
@@ -59,6 +67,13 @@ export const roadmapLabels = z.object({
partnership: z.string(),
launch: z.string(),
}),
// Tag vocabulary — see `phase`/`note` on roadmapItem. Open records so a new
// key only has to be added to the JSON, not here; XahauRoadmap.astro fails
// the build if an item points at a key that doesn't exist.
tags: z.object({
phases: z.record(z.string(), z.string()),
notes: z.record(z.string(), z.string()),
}),
foot: z.string(),
})