Landing Pages — Meta Portal (meta.koder.dev)
Estrutura, IA, pipeline de render, deploy e governança do portal público de documentação da Koder Stack em `meta.koder.dev`. Renderiza o conteúdo de `meta/docs/{stack,ia,cryptography,blockchain}/` como HTML estático navegável, com nav hierárquico por tipo de documento (RFC, spec, policy, registry, module, runbook, compendium), search client-side, theme light/dark, i18n EN/PT. Distinto de landings de produto, área, sector, institucional, catálogo, packages e specs — é um **portal-indexador de documentos**, não uma landing-vendedor.
Landing Pages — Meta Portal (meta.koder.dev)
1. Visão Geral
meta.koder.dev é o *ortal público de documentação*da Koder Stack. Renderiza o conteúdo de meta/docs/ do monorepo como site estático navegável.
Não é uma landing de produto, marca, área ou spec individual — é um *ndexador de documentos* Tem nav hierárquico por tipo (RFC, spec, policy, registry, module, runbook, compendium), uma página por arquivo fonte, search clientside e crosslinks resolvidos.
*istinto de:*
specs/landing-pages/products.kmd— landings de *m*produtospecs/landing-pages/specs.kmd— landing de *ma*spec/formato (KVG, KPKG)specs/landing-pages/areas.kmd— landing de Área L2 (foundation, ai, …)specs/landing-pages/institutional.kmd— landings sobre a Koder (www, company)specs/landing-pages/catalog.kmd— Hub catalog (hub.koder.dev)specs/landing-pages/packages.kmd— página individual de pacote no Hub
Histórico canônico (20260524):
- ~10 landings de Área (
meta/sites/areas),meta/sites/brand/e
meta/sites/_ecosystem_gen.pyreferenciaramdocs.koder.devdesde 2026-Q2 como "Public documentation" (sempre dead link). - Sessão de 2026
0524 turn 3: owner pediu site pro conteúdo demeta/. Pragmaticamente decidido construirdocs.koder.devreusando o nome já referenciado. Implementação concluída em 5 turns (spec, renderer, vhost, audit, deploy paralelo) — portal shipped com 652 docs. - Mesma sessão turn 12: owner observou que o nome
docs.estásemanticamente errado pro conteúdo (RFCsspecspolicies/registries = "meta", não "docs do usuário"). Decisão revertida: canonical é
meta.koder.dev, mirror direto do L1 domainmeta/do monorepo. - Cutover atomic agendado (Phase B) quando
infra/net/jetliberaro lock atual (jet#160 Phase 1) — ver
jet#NNN follow-up ticketno umbrella METADOCS131.docs.koder.dev→ 301 →meta.koder.dev, landings editorialmente atualizadas, per-product docs ficam em<product>.koder.dev/docs/quando os produtos shipam.
2. Escopo de Conteúdo
2.1 Em escopo (público, vai pro portal)
| Fonte | Tipo | Sub-path no portal |
|---|---|---|
meta/docs/stack/rfcs/ |
RFCs | /rfcs/ |
meta/docs/stack/specs/ |
Specs normativas | /specs/ |
meta/docs/stack/policies/ |
Policies comportamentais | /policies/ |
meta/docs/stack/registries/ |
Registries (fontes de verdade) | /registries/ |
meta/docs/stack/modules/ |
Module catalog | /modules/ |
meta/docs/stack/runbooks/ |
Runbooks operacionais públicos | /runbooks/ |
meta/docs/stack/releases/ |
Release notes consolidadas | /releases/ |
meta/docs/ia/compendium/ |
Compendium de IA | /compendiums/ia/ |
meta/docs/cryptography/compendium/ |
Compendium de criptografia | /compendiums/cryptography/ |
meta/docs/blockchain/compendium/ |
Compendium de blockchain | /compendiums/blockchain/ |
2.2 Fora de escopo (NUNCA publicar)
meta/context/— runbooks internos, hooks de IA, credenciais,notices, recaps. *rivado por contrato.*
meta/brand/— assets de marca (vivem embrand.koder.dev)meta/sites/— landings (cada uma tem seu próprio domínio)- Qualquer arquivo com frontmatter
visibility: internalouaudit: private(ver §6.3) meta/docs/stack/backlog/— tickets de trabalho interno
2.3 Avaliação per-diretório (decidir caso a caso)
meta/docs/platform/— possivelmente público; auditar conteúdometa/docs/trust/— possivelmente público; auditar conteúdometa/docs/flow-releases/— público se substituirflow.koder.dev/releases; senão, manter privadometa/docs/docs/— meta-docs sobre o sistema de docs; provavelmente públicometa/docs/stack/diagrams/,presentation/,build/— públicoscomo assets/anexos, não páginas próprias
3. URL Canônica
Padrão: https://meta.koder.dev/<category>/<path>/
<category>∈ {rfcs,specs,policies,registries,modules,runbooks,releases,compendiums}<path>espelha 1:1 a estrutura de subdir na fonte, com.kmd/.mdremovidos e nomes preservados
- Trailing slash sempre presente (URLs com slash final →
index.htmldo diretório virtual)
- Casos especiais:
- Homepage:
https://meta.koder.dev/(não/index.html) - Search:
https://meta.koder.dev/search/?q=<query>(client-side) - Sitemap:
https://meta.koder.dev/sitemap.xml - 404:
https://meta.koder.dev/404.html
- Homepage:
*xemplos:*
| Fonte | URL |
|---|---|
meta/docs/stack/rfcs/stack-RFC-001-kdb-as-unified-data-plane.kmd |
/rfcs/stack-RFC-001-kdb-as-unified-data-plane/ |
meta/docs/stack/specs/auth/oauth-flow.kmd |
/specs/auth/oauth-flow/ |
meta/docs/stack/policies/hyperscale-first.kmd |
/policies/hyperscale-first/ |
meta/docs/stack/registries/component-names.md |
/registries/component-names/ |
meta/docs/ia/compendium/01-models.md |
/compendiums/ia/01-models/ |
*egra de imutabilidade* URLs uma vez publicadas não mudam. Renomes em meta/docs/ precisam de redirect 301 em /redirects.toml consumido pelo Jet (#131.5 audit).
4. Estrutura do Arquivo de Site
meta/sites/docs/
├── _layouts/ ← Templates HTML (não servidos)
│ ├── home.html
│ ├── category.html ← Listing de uma categoria
│ ├── doc.html ← Página de um documento
│ ├── 404.html
│ └── search.html
├── _assets/
│ ├── ecosystem.css ← Symlink pra meta/sites/ecosystem.css
│ ├── docs.css ← Estilos específicos (sidebar, TOC, code blocks)
│ ├── docs.js ← Search + theme + i18n
│ ├── lunr.min.js ← Search engine (vendored ~100KB)
│ ├── search-index.json ← Gerado pelo renderer
│ ├── icon.svg
│ └── og-image-default.png
├── index.html ← Gerado: homepage
├── <category>/ ← Gerado per category
│ ├── index.html
│ └── <doc-slug>/
│ └── index.html
├── search/index.html
├── sitemap.xml
└── 404.htmlTodos os HTMLs servidos são *erados*pelo renderer (#131.2); nenhum HTML é escrito à mão exceto os _layouts/. O diretório _layouts/ e _assets/ (exceto o que for gerado) *ão commitados*no monorepo; o resto (<category>/, search/, sitemap.xml, 404.html, index.html, search-index.json) é *uild artifact*— gitignored, regenerado em CI a cada push (per policies/hyperscale-first.kmd).
5. Information Architecture
5.1 Homepage (/)
Estrutura (top→bottom):
- *av*(sticky, idêntica a outras landings — ver §8)
- *ero*centralizado:
- Eyebrow: "The Koder Stack"
- H1 grande: "Documentation" (com palavra em accent gradient)
- Lead 2 frases: "RFCs, specifications, policies and registries
that define how every Koder component is built and operated. Browse, search, link."
- Search bar full-width (foco automático em desktop)
- 2 CTAs: "Browse RFCs" + "Browse Specs"
- *ategory grid*— 8 cards (uma por categoria de §2.1):
- Ícone + título + contagem ("47 RFCs", "180 specs", "32 policies", …)
- Card inteiro clicável →
/<category>/ - Counts injetados pelo renderer no build
- *ecently updated*— lista das 10 últimas modificações
(extraídas de
git logno build) - *eatured*— opcional, curado: links pra 3-5 docs de entrada
(RFC
001, headlessfirst.kmd, multi-tenancy/contract.kmd, …) - *ooter dark*(idêntico a
institutional.kmd§2.8)
5.2 Category listing (/<category>/)
Estrutura:
- Nav
- Breadcrumb:
Home / <Category> - Header: nome da categoria + descrição de 1 linha + total
- *iltros*
- Por sub-area (specs:
auth/,i18n/,themes/, …) - Por status (RFCs: draft / accepted / superseded; specs:
pre-normative / normative / draft)
- Por data (modified last 7d / 30d / 90d / all)
- Por sub-area (specs:
- *ista de docs*— tabela ou cards:
- Nome + sub
path + 1line summary (do frontmattersummary:) - Status badge
- Last-modified date
- Audit status se aplicável
- Nome + sub
- Footer
5.3 Document page (/<category>/<slug>/)
Estrutura (layout 3 colunas em desktop, stacked em mobile):
- Nav
- *eft sidebar*(sticky, scroll-independente):
- Navegação da categoria atual (árvore expandida no doc atual)
- *ain content*
- *ight sidebar*(TOC):
- Lista de headings H2/H3 do doc
- Scroll-spy: destaca seção atual
- Footer global
5.4 Search (/search/?q=…)
- Client-side, lunr.js indexa título + frontmatter + headings (não
full text — keeps index <500KB)
- Resultados agrupados por categoria
- Highlight do termo nos snippets
6. Render Pipeline
Implementação: dev/koder-tools/cmd/koder-docs-render/ (Go) — ticket METADOCS131.2. Esta seção é o *ontrato*do renderer.
6.1 Input
- Walk de
meta/docs/{stack,ia,cryptography,blockchain}/(e diretóriospromovidos por §2.3)
- Aceita
.kmde.md. Frontmatter YAML obrigatório (sem frontmatter→ log warning + skip ou render como "untyped doc")
- Respeita
.docsignore(lista de globs) em cada diretório raiz
6.2 Parser
- Markdown: reutilizar parser canônico da Stack (mesmo de
kmd render); fallbackgoldmarkse kmd parser indisponível - Frontmatter:
yaml.v3 - Cross
links: resolver `[texto](relativepath.kmd)` → URL canônicado portal (ver §3);
[[wiki-link]]→ busca porname:no frontmatter de todos os docs indexados, falha emite warning
6.3 Visibility filter
Skip arquivo se:
- Frontmatter contém
visibility: internal - Frontmatter contém
audit: private - Path bate com qualquer entrada de
meta/sites/docs/_excluded.toml(escape hatch curado)
6.4 Output
meta/sites/docs/<category>/<slug>/index.htmlper docmeta/sites/docs/<category>/index.htmlper categoriameta/sites/docs/index.htmlhomepagemeta/sites/docs/search/index.html+_assets/search-index.jsonmeta/sites/docs/sitemap.xml(Google + IndexNow)meta/sites/docs/404.htmlmeta/sites/docs/redirects.toml(Jet-consumível, se houver renames detectados)
6.5 Metadata extraída do frontmatter
| Frontmatter key | Onde aparece no HTML |
|---|---|
name / title |
<title>, <h1>, og:title |
summary |
<meta description>, og:description, listing card |
status |
badge bar + filter em listing |
type |
category routing |
mandatory: true |
"Mandatory" badge no header |
triggers |
section "When this applies" (collapsible) |
references |
rendered como linked list no rodapé do doc |
audit |
badge "Audit: date" |
facets |
tags clicáveis |
6.6 Hyperscale gate
Per policies/hyperscale-first.kmd: renderer *EVE*escalar a 10× o volume atual sem mudança arquitetural (~5k docs). Decisões:
- HTML estático puro, sem SSR/CSR runtime
- Build incremental: hash do arquivo fonte + frontmatter; só
re-renderiza o que mudou
- Search index gerado em pass único, paralelizado por worker
- Sem JS bundlers —
docs.jsé vanilla JS direto
7. Head — Meta Tags
Template aplicado a TODA página:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{page.title}} — Koder Docs</title>
<meta name="description" content="{{page.summary}}">
<meta name="theme-color" content="#0b1120">
<link rel="canonical" href="https://meta.koder.dev{{page.url}}">
<!-- Open Graph -->
<meta property="og:title" content="{{page.title}} — Koder Docs">
<meta property="og:description" content="{{page.summary}}">
<meta property="og:type" content="article">
<meta property="og:url" content="https://meta.koder.dev{{page.url}}">
<meta property="og:image" content="https://meta.koder.dev{{page.og_image | default('/_assets/og-image-default.png')}}">
<meta property="og:image:width" content="1200">
<meta property="og:image:height" content="630">
<!-- Twitter -->
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="{{page.title}} — Koder Docs">
<meta name="twitter:description" content="{{page.summary}}">
<meta name="twitter:image" content="https://meta.koder.dev{{page.og_image | default('/_assets/og-image-default.png')}}">
<link rel="icon" type="image/svg+xml" href="/_assets/icon.svg">
<script>
(function(){
const s = localStorage.getItem('theme');
const dark = s ? s === 'dark' : matchMedia('(prefers-color-scheme:dark)').matches;
if (dark) document.documentElement.setAttribute('data-theme','dark');
})();
</script>
<link rel="stylesheet" href="/_assets/ecosystem.css">
<link rel="stylesheet" href="/_assets/docs.css">
</head><title>max 60 chars; trunca{{page.title}}se preciso (renderer warn)og:type = "article"em doc pages,"website"em homepage/category listingsog:imageper page é opcional; default =og-image-default.png(Koder Docs branded)
8. Nav
Idêntica ao padrão de outras landings (ecosystem.css):
<nav>
<div class="nav-inner">
<a class="nav-brand" href="/"><img src="/_assets/icon.svg" alt="">Koder Docs</a>
<button aria-label="Menu" class="nav-toggle" onclick="...">☰</button>
<div class="nav-links">
<a href="/rfcs/">RFCs</a>
<a href="/specs/">Specs</a>
<a href="/policies/">Policies</a>
<a href="/registries/">Registries</a>
<a href="/compendiums/">Compendiums</a>
<button id="lang-btn" onclick="toggleLang()">EN</button>
<button class="theme-toggle" onclick="toggleTheme()">…</button>
</div>
</div>
</nav>Versão sticky com backdrop-filter: blur(16px). Ordem dos links é canônica (RFCs antes de Specs antes de Policies, por densidade de referência).
9. CSS — Tokens
Reusar meta/sites/ecosystem.css (mesma base de areasbrandcompany). Estilos específicos do portal em meta/sites/docs/_assets/docs.css:
- Sidebar tree (left + right TOC)
- Code blocks com syntax highlighting (Prism vendored ou highlight.js)
- Tables responsivas (scroll-x em mobile)
- Badge bar (status, mandatory, audit)
- Search results
*heme* lightdark per `specsthemes/light-dark.kmd`. Toggle JS idêntico ao das outras landings.
*okens visuais* per specs/themes/verge.kmd — usar Verge default.
*ontes* per specs/fonts/typography.kmd:
- Sans: Inter (self-hosted woff2 via
/_assets/fonts/inter.woff2) - Mono: JetBrains Mono (self-hosted)
- *roibido*Google Fonts / jsDelivr / unpkg
10. JavaScript — Comportamentos
_assets/docs.js (vanilla, ~10KB minified):
- Theme toggle (idêntico a outras landings)
- Language toggle EN ↔ PT-BR (i18n; conteúdo é EN por
policies/language.kmd, mas chrome traduzível) - Mobile nav hamburger
- TOC scroll-spy
- Sidebar tree expand/collapse + persistência em
localStorage - Search input (homepage + página search): query lunr index,
renderiza resultados ou redireciona pra
/search/?q=… - Copy
toclipboard em code blocks (button hover) - Anchor links em H2/H3 (hover icon → copy URL com fragment)
lunr.min.js carregado *ó na rota*/search/ (lazy) — não penaliza páginas de leitura.
11. Dead-Link Audit
A spec *andata*que ao primeiro deploy em produção, o renderer gere um relatório audit/dead-links-<date>.json listando todas as refs a meta.koder.dev
index.html, meta/sites/brand/index.html, meta/sites/_ecosystem_gen.py) e marque cada uma como:
- ✅
resolves— path canônico existe - 🔁
redirects-to: <new-path>— entrada emredirects.tomlnecessária - ❌
broken— bloqueia release até #131.5 decidir destino
CI gate: build do portal falha se houver broken sem resolução.
12. i18n
- Conteúdo (doc body) *ÃO*é traduzido — é EN por
policies/language.kmd - Chrome (nav, footer, breadcrumbs, status badges, "Recently
updated") É traduzido EN ↔ PT-BR
- Toggle
EN/PTno nav (mesmo padrão das outras landings) - Default por geo / browser language; persiste em
localStorage - T1-T6 da spec
specs/i18n/contract.kmdaplicam
13. Acessibilidade
- WCAG 2.1 AA
- Skip
tocontent link no topo - Sidebar tree navegável por teclado (arrow keys)
- Theme toggle com
aria-label+aria-pressed - TOC com
aria-current="location"no item ativo - Code blocks com
role="region"earia-label="Code sample" - Tabela de conformance per page em audit periódico (#131 followup)
14. SEO
sitemap.xmlgerado no build, submetido ao Google Search Console- Per-page meta tags (§7)
robots.txtem/_assets/robots.txt—Allow: /em prd,Disallow: /em stgdev (per `policiesenvironments.kmd`)- IndexNow ping no deploy de produção (lista de URLs alteradas)
- Schema.org
TechArticleJSON-LD em doc pages
15. Deploy
Per policies/web-server.kmd (Jet only) + policies/environments.kmd:
| Ambiente | Host | Branch source | noindex |
|---|---|---|---|
dev.meta.koder.dev |
s.forge | dev |
true |
stg.meta.koder.dev |
s.forge | staging |
true |
meta.koder.dev (prd) |
s.forge | main |
false |
DNS A record provisionado via ClouDNS (meta/context/infrastructure/dns.md). TLS via Jet autocert (LE/ACME).
Pipeline de deploy:
- CI roda
koder-docs-render --env <env>no monorepo - Output em
meta/sites/docs/(sub-paths gitignored) rsyncpro/var/www/meta.koder.dev/no s.forge- Jet reload (zero-downtime)
- Smoke:
curl -I https://meta.koder.dev/→ 200 + TTFB <500ms - Lighthouse: a11y ≥ 95, perf ≥ 90, SEO = 100
16. Performance Targets
| Métrica | Target |
|---|---|
| TTFB | <200ms (CDN/edge se necessário, futuro) |
| LCP | <1.5s |
| CLS | <0.05 |
| Page weight (homepage) | <100KB (sem search index) |
| Page weight (doc page) | <150KB (sem code samples grandes) |
| Search index | <500KB |
| Build time (full) | <60s pra ~500 docs |
| Build time (incremental) | <5s |
17. Governança
- *wner* Koder Stack (Rodrigo)
- *pec maturity gate* v1.0 normative quando #131.2.3.4.5.6/.7
do umbrella META
DOCS131 estiverem done + lighthouse scores atingidos + dead-link audit limpa em 2 builds consecutivos - *ersioning* a spec do portal segue semver per
specs/landing-pages/specs.kmd §6 - *udit*
koder-spec-audit landing-pages --slug docs(a serimplementado pelo audit harness em
dev/koder-tools/)
18. Decisões Em Aberto
- *earch backend long
term* lunr.js (v0) → kdbsearch quandorfcs/stack-RFC-001-kdb-as-unified-data-plane.kmdentregar layer de busca. Decisão revisitada no kickoff de #131.2. - *ersionamento de docs* always-latest (HEAD) vs por tag
(v1.0, v1.1). Default v0: always-latest; versões anteriores acessíveis via Flow se requestado. Revisitar quando portal tiver ≥1 ano de tráfego.
- *G image generation per page* usar
kicon generate --targets ogper doc, ou template estático compartilhado por categoria? Default v0: estático por categoria (8 imagens curadas).
- *omments / feedback* deixar fora do v0. Avaliar Giscus
(GitHub
backed) vs solução selfhosted em v2. - *ersioned dark mode* usar Verge default ou expor preset
switcher como no KDS? Default v0: Verge default, sem switcher.
19. Referência Cruzada
specs/landing-pages/institutional.kmd— padrão de footer dark + navspecs/landing-pages/specs.kmd— padrão de docaspagespecs/kmd/— parser canônicopolicies/hyperscale-first.kmd— gate de build incrementalpolicies/reuse-first.kmd— reuso deecosystem.cssmeta/sites/_ecosystem_gen.py— gerador atual de landings de Área(referencia o dead link
meta.koder.dev/ecosystem)- META
DOCS131 — umbrella ticket do programa - JET-161 — vhost ticket
20. Estado Atual (20260524)
| Sub-stream | Ticket | Status |
|---|---|---|
| Landing spec | #131.1 | ✅ esta spec (v0.1.0 pre-normative) |
| Renderer pipeline | #131.2 | pending |
| Templates + nav | #131.3 | pending |
| Vhost + TLS | JET-161 | pending (blocked on #131.1+#131.2) |
| Dead-link audit + fix | #131.5 | pending |
| OG image + brand assets | #131.6 | pending |
| i18n chrome | #131.7 | pending |