Para máquinas
Documentação para agentes
Como ler este portfólio programaticamente: endpoints, formatos, cache, política de bots e as interfaces que este site deliberadamente não implementa.
Último build: 2026-08-02T13:31:08.710Z
Finalidade
Este é um portfólio pessoal. Tudo que um cliente automatizado consegue ler aqui já está publicado como HTML na mesma origem — as interfaces legíveis por máquina existem para que um agente não precise raspar uma página estilizada para responder a uma pergunta sobre o trabalho desta pessoa.
Todas as representações são geradas a partir de um único dataset tipado no repositório. A página HTML, o equivalente em Markdown, a API JSON, a descrição OpenAPI, as ferramentas MCP e o JSON-LD leem da mesma fonte, então não podem discordar sobre um fato.
Formatos e negociação
HTML e Markdown usam URLs distintas para manter inequívoco o comportamento de caches intermediários. Use `/api/v1/markdown/en` ou `/api/v1/markdown/pt` para Markdown.
As rotas explícitas tornam a representação retornada independente dos cabeçalhos da requisição.
- `curl https://enoquesousa.com/api/v1/markdown/pt` — Markdown, `200`.
- `curl https://enoquesousa.com/pt` — HTML, `200`, exatamente o que um navegador recebe.
- `curl https://enoquesousa.com/pt` — HTML, independentemente de `Accept`.
- Assets, rotas de API e documentos `.well-known` nunca são negociados para Markdown.
A API REST
Pública, anônima e somente leitura. As respostas são `{ data, meta }`; `meta.contentRevision` é um digest do conteúdo, então um cliente consegue saber se sua cópia em cache continua atual sem comparar payloads.
Todos os endpoints aceitam `?locale=en|pt`, com padrão `en`. Um idioma não reconhecido recebe `400` em vez de um fallback silencioso. Slugs de projeto inexistentes retornam `404` com a lista de slugs reais. Métodos não suportados retornam `405` com um cabeçalho `Allow`.
| Método | Caminho | Tipo de mídia | Finalidade |
|---|---|---|---|
| GET | /robots.txt | text/plain | Preferências de rastreamento e a política Content-Signal. |
| GET | /sitemap.xml | application/xml | Páginas HTML indexáveis, com alternativas hreflang. |
| GET | /llms.txt | text/plain | Índice curto deste site para modelos de linguagem. |
| GET | /llms-full.txt | text/plain | O portfólio inteiro em Markdown. |
| GET | /openapi.json | application/json | Descrição OpenAPI 3.1 da API REST. |
| GET | /.well-known/api-catalog | application/linkset+json | Catálogo RFC 9727 apontando para a API, sua descrição, documentação e health. |
| GET | /.well-known/agent-skills/index.json | application/json | Índice das Agent Skills publicadas, com digest de cada artefato. |
| GET | /.well-known/agent-skills/enoque-sousa-portfolio/SKILL.md | text/markdown | O artefato da skill em si. |
| GET | /api/health | application/json | Liveness, versão do schema e revisão do conteúdo. Nunca cacheado. |
| GET | /api/v1 | application/json | Raiz da API versionada; lista os próprios recursos. |
| GET | /api/v1/profile | application/json | Nome, cargo, headline, posicionamento, links públicos. |
| GET | /api/v1/projects | application/json | Trabalho selecionado. Filtros: ?featured=true, ?tech=Python. |
| GET | /api/v1/projects/{slug} | application/json | Um único projeto pelo slug estável. |
| GET | /api/v1/skills | application/json | Áreas de atuação, stack por grupo, lista plana de tecnologias. |
| GET | /api/v1/experience | application/json | Cargos, do mais recente ao mais antigo, com início e fim ISO. |
| GET | /api/v1/certifications | application/json | Certificações e cursos publicados. |
| GET | /api/v1/contact | application/json | Canais de contato já impressos na página. |
| GET | /api/v1/markdown/{locale} | text/markdown | O portfólio em Markdown, endereçado diretamente. |
Versionamento
O caminho da API carrega a versão maior (`/api/v1`). `meta.schemaVersion` carrega o semver do payload: um incremento menor adiciona campos, um maior altera ou remove. Slugs de projeto são identificadores estáveis e nunca são reaproveitados para outro projeto.
`meta.updatedAt` é o timestamp de build do deploy em execução, não uma data editada à mão.
Cache
O conteúdo só muda quando um novo build é publicado, então os recursos JSON usam `public, max-age=600, s-maxage=3600, stale-while-revalidate=86400` e os documentos de descoberta têm cache mais longo. `/api/health` é `no-store` — um health check em cache reporta a saúde do cache.
Páginas HTML são `private, max-age=0, must-revalidate`. As rotas Markdown explícitas têm cache público e não variam por cabeçalhos da requisição.
Bots e uso do conteúdo
O `robots.txt` declara uma única política — `ai-train=no, search=yes, ai-input=yes` — no grupo curinga e, de forma idêntica, em um grupo que nomeia os crawlers de IA conhecidos, porque um crawler obedece apenas ao grupo mais específico que corresponde a ele. Nada é bloqueado: este é um portfólio, e ser encontrado é o objetivo.
Leia isso como: indexe, cite, use para responder perguntas sobre esta pessoa. Nenhuma permissão é concedida para uso como dado de treinamento. O `robots.txt` é uma declaração de preferência para clientes bem-comportados, não um controle de acesso, e não é tratado como tal aqui.
Autenticação
Não há, e isso é uma decisão em vez de uma omissão. Nada aqui é protegido, nada é gravável e nenhuma operação age em nome de alguém — portanto não existe recurso que um authorization server pudesse proteger. Nenhum documento de descoberta OAuth ou OpenID Connect é publicado, porque publicar um anunciaria um fluxo que não existe.
Limites e o que está ausente
A descoberta MCP está adiada até que o ciclo de vida do transporte e os controles de edge passem por uma auditoria de produção separada. Os endpoints GET somente leitura são cacheáveis e não têm limite separado.
Deliberadamente não implementados: descoberta OAuth e OpenID Connect, metadados de recurso protegido, diretórios de assinatura Web Bot Auth, WebMCP e os protocolos de comércio para agentes. Cada um é inaplicável a um site sem recursos protegidos ou depende de uma especificação instável demais para publicar. O repositório documenta o raciocínio item a item.
Problemas com estas interfaces
Se um endpoint aqui estiver errado, inacessível ou descrever algo de forma imprecisa, o caminho mais rápido é o e-mail — o mesmo endereço publicado na seção de contato do portfólio.