prometeu-studio/discussion/workflow/agendas/AGD-0012-studio-editor-document-vfs-boundary.md
2026-03-31 08:00:10 +01:00

201 lines
14 KiB
Markdown

---
id: AGD-0012
ticket: studio-editor-document-vfs-boundary
title: Definir um boundary de VFS documental para tree/view/open files no Code Editor do Studio
status: in_progress
created: 2026-03-31
resolved: 2026-03-31
decision: DEC-0009
tags:
- studio
- editor
- workspace
- vfs
- filesystem
- boundary
---
## Pain
O `Code Editor` do Studio ja fechou a primeira wave como shell editorial read-only, mas a composicao concreta ainda instancia diretamente os servicos que leem arvore e conteudo do filesystem.
Isso deixa uma ambiguidade arquitetural:
- o shell do workspace deveria coordenar layout, sessao e sincronizacao;
- mas hoje ele ainda conhece diretamente os adaptadores de leitura estrutural e de leitura de documento;
- e nao esta explicito se a proxima evolucao deve continuar como `filesystem services` locais ou subir para um boundary mais claro de `document/tree VFS`.
Sem fechar esse ponto agora, o editor corre risco de crescer com responsabilidades misturadas:
- tree snapshot;
- open-file buffers;
- refresh/watchers;
- overlays de documento em memoria;
- e futuras fontes nao estritamente filesystem-backed.
## Context
Domain owner: `studio`
Owner surface: `docs/specs/studio`
Superficies relevantes:
- `docs/specs/studio/5. Code Editor Workspace Specification.md` ja exige separacao entre structural snapshot e opened-file content, mantendo o filesystem como source of truth nesta wave;
- `discussion/lessons/DSC-0010-studio-code-editor-workspace-foundations/LSN-0026-read-only-editor-foundations-and-semantic-deferral.md` consolida que o Studio possui o shell editorial, nao um IDE semantico completo;
- `EditorWorkspace` ainda instancia diretamente `EditorProjectSnapshotService` e `EditorFileBufferLoader`;
- `EditorProjectSnapshotService` e `EditorFileBufferLoader` usam `Files.*` diretamente como backend concreto.
- o workspace Gradle ja reserva `prometeu-lsp:prometeu-lsp-api` e `prometeu-lsp:prometeu-lsp-v1`, mas hoje esses modulos ainda nao tem codigo;
- os roadmaps de LSP tratam `prometeu-lsp` como superficie futura para handlers/endpoints semanticos e itens como `didChangeWatchedFiles`.
Clarificacao importante para esta discussion:
- quando falamos em `VFS` aqui, nao estamos propondo um filesystem universal do produto;
- o packer continua com ownership proprio de runtime/workspace/asset semantics;
- as entidades nao se veem por padrao;
- o recorte aqui e um boundary do `Code Editor` para `tree`, `view` e `open files`, inclusive conteudo em memoria.
## Open Questions
- [x] Nesta etapa, o boundary transporta apenas o que o `workspace editor` ja tem hoje; nada novo entra no escopo funcional.
- [x] O `prometeu-vfs` nao deve expor apenas RPC; ele tambem deve receber e emitir um subconjunto selecionado de eventos como parte explicita da propria API.
- [x] O `Project Navigator` consome uma entidade que representa a arvore inteira, sem acessar filesystem diretamente, mas deve poder requerer atualizacoes mais pontuais do que um reload completo.
- [x] A `tree` do `prometeu-vfs` deve ser estrutural e de dados apenas, nao uma tree visual nem um view model de UI.
- [x] O `open files` passa a abrir a partir do `prometeu-vfs`, inclusive quando o backend concreto continuar sendo o disco.
- [x] Regras de arquivos, plugins e de suporte ou nao suporte pertencem ao `prometeu-vfs`; o Studio apenas apresenta o erro/estado ao usuario.
- [x] Nesta primeira wave, eventos publicos ficam de fora; tudo permanece interno ate existir necessidade clara de exposicao contratual.
- [x] `Watchers` ficam fora desta primeira decisao; `refresh` permanece somente manual.
- [x] O boundary nasce como primitive util para o dominio `studio`; hoje o editor consome, e futuramente o `prometeu-lsp` podera consumir tambem.
- [x] O `document/tree manager` vive na sessao de projeto do Studio, e o snapshot do `prometeu-vfs` cobre apenas conteudo do projeto.
- [x] Criar um novo `prometeu-vfs` e manter `prometeu-lsp` reservado para a camada futura de protocolo/handlers parece melhor do que renomear o namespace atual.
## Options
### Option A - Manter servicos filesystem locais no editor
- **Approach:** Continuar com `EditorProjectSnapshotService` e `EditorFileBufferLoader` como helpers concretos do workspace, extraindo apenas pequenos refinamentos locais.
- **Pro:** Menor custo imediato e menos abstracao.
- **Con:** O shell continua acoplado ao backend concreto e a evolucao para overlays, watchers ou backends alternativos fica difusa.
- **Maintainability:** Media para baixa. Funciona enquanto o editor permanecer estritamente read-only e filesystem-first.
### Option B - Extrair portas pequenas separadas, sem chamar isso de VFS
- **Approach:** Definir interfaces independentes para `project tree snapshot` e `document content loading`, ambas filesystem-backed por baixo.
- **Pro:** Resolve o acoplamento principal com mudanca pequena e preserva clareza.
- **Con:** Pode virar um VFS fatiado informalmente, sem um modelo claro quando overlays de memoria entrarem.
- **Maintainability:** Media. Boa transicao curta, mas com risco de proliferar portas parciais.
### Option C - Definir um VFS documental estreito para o Code Editor
- **Approach:** Criar um boundary explicito do editor que seja owner de arvore virtual do projeto e documentos abertos/em memoria, com backend inicial filesystem-backed e overlays de sessao como extensao prevista.
- **Pro:** Fecha a fronteira certa: o workspace consome um modelo de documentos/arvore e deixa de conhecer `Files.*` ou loaders concretos.
- **Con:** Exige nomear melhor contratos, identidade de documento, estrategia de refresh e como snapshot estrutural convive com buffers abertos.
- **Maintainability:** Forte. Preserva a intencao de shell editorial e abre caminho limpo para write wave, overlays e fontes alternativas sem acoplar isso ao packer.
### Option D - Criar um novo modulo `prometeu-vfs` com lifecycle de projeto no Studio
- **Approach:** Criar um modulo-base de VFS/document manager (`prometeu-vfs`) que o Studio instancia por projeto, fora do foco do workspace, com watchers/refresh/overlays encapsulados ali; o editor vira consumidor desse servico, enquanto `prometeu-lsp` permanece reservado para a futura camada de protocolo/handlers. O modulo deve expor uma API mista de chamadas RPC e um subconjunto disciplinado de eventos publicos.
- **Pro:** Alinha melhor a ownership real do estado documental, porque ele continua vivo mesmo sem o `Code Editor` estar ativo; tambem prepara o caminho para um futuro `prometeu-lsp` consumir o mesmo substrate em vez de reinventar sincronizacao.
- **Con:** Obriga a decidir desde ja a topologia entre `studio`, `vfs` e um futuro `lsp`, alem de exigir definicao disciplinada da fronteira entre eventos publicos e eventos internos para nao vazar detalhes internos como API acidental.
- **Maintainability:** Forte, desde que o scope continue estrito a documentos/arvore de projeto e nao derive para um filesystem universal do produto.
### Option E - Criar um VFS generico de Studio desde ja
- **Approach:** Elevar o boundary para uma primitive ampla do Studio, candidata a servir editor, assets, debugger e outras workspaces.
- **Pro:** Promete reutilizacao ampla.
- **Con:** Generaliza antes de existir evidencia suficiente de consumo compartilhado e arrisca misturar dominios que hoje precisam continuar separados.
- **Maintainability:** Baixa neste momento. A abstracao tende a nascer grande demais e cedo demais.
## Discussion
O ponto principal nao e substituir o disco por uma simulacao abstrata.
O ponto principal e impedir que o `Code Editor` continue dono acidental de concerns que deveriam morar em um boundary proprio de documentos e arvore.
O estado normativo atual ja separa corretamente:
1. snapshot estrutural do projeto para navegacao;
2. buffers de documentos abertos para sessao;
3. filesystem como source of truth na primeira wave.
O que falta e transformar essa separacao conceitual em uma fronteira arquitetural explicita.
Se o boundary nascer estreito, ele pode continuar filesystem-backed sem conflito:
- o navigator pede uma arvore/snapshot;
- o open-files pede documentos;
- overlays de memoria podem passar a viver no mesmo boundary quando write/draft semantics entrarem;
- e o workspace continua coordenando UX, nao I/O.
O novo ponto trazido nesta discussion refinou ainda mais o boundary correto:
- o estado documental do projeto pode precisar continuar vivo mesmo quando o `Code Editor` nao estiver no foco;
- refresh manual e reconciliacao de documento sao concerns de runtime do boundary, nao do layout do workspace;
- portanto, o owner mais coerente deixa de ser o `EditorWorkspace` e passa a ser um servico de projeto do Studio que o editor consome.
Outro fechamento importante e que esse servico nao deve ser pensado como biblioteca puramente sincrona de funcoes:
- o `prometeu-vfs` deve oferecer chamadas de API para comandos/queries diretas;
- o modulo pode manter eventos internos como parte do seu runtime;
- mas nesta primeira wave nenhum evento precisa sair como API publica;
- isso preserva flexibilidade interna enquanto o boundary estrutural e documental ainda esta sendo estabilizado.
Nesse modelo, a pilha correta tende a ser:
1. `Studio project session` instancia o manager documental;
2. `prometeu-vfs` ou equivalente implementa tree/document/watchers/overlays;
3. `EditorWorkspace` observa e consome esse estado;
4. um futuro `prometeu-lsp` pode consumir o mesmo substrate acima dele, e nao o contrario.
Um fechamento importante desta agenda e que a palavra `tree` em `prometeu-vfs` significa estrutura de dados do projeto, nao componente visual:
- o `prometeu-vfs` deve publicar nos estruturais, paths, parent/children, tipos de entrada, identidades e metadados documentais necessarios;
- o `prometeu-vfs` nao deve carregar concerns de UI como expansao visual, selecao, foco, scroll, reveal, icones ou chrome de navigator;
- o `Project Navigator` do Studio continua owner do tree visual e de qualquer view model derivado para apresentacao;
- tags ou metadados produzidos pelo `prometeu-vfs` podem informar a UI, mas a decisao de como renderizar continua no Studio.
O mesmo vale para o modelo de comunicacao:
- RPC cobre comandos/queries como abrir documento, pedir snapshot, reconciliar, listar documentos ou obter conteudo atual;
- eventos internos podem cobrir transicoes observaveis do runtime como snapshot atualizado, documento mutado, divergencia detectada ou refresh concluido;
- esses eventos permanecem encapsulados nesta wave;
- a API oficial inicial fica concentrada em RPC/comandos/queries, sem publication obrigatoria para fora do modulo.
O fato de `prometeu-lsp` ainda estar vazio torna qualquer mudanca barata em codigo, mas a decisao mais limpa continua sendo criar `prometeu-vfs` como modulo novo:
- o nome `prometeu-lsp` ja esta referenciado nos roadmaps como superficie futura de protocolo/handlers;
- renomear agora e barato em codigo, mas continua sendo ruidoso editorialmente;
- criar `prometeu-vfs` preserva a hierarquia conceitual certa: `vfs` como substrate, `lsp` como consumidor futuro.
Isso e diferente de um `VFS universal`:
- nao absorve regras do packer;
- nao redefine ownership de assets;
- nao cria dependencia cruzada entre domínios;
- e nao exige que todas as workspaces do Studio passem a usar o mesmo modelo desde o dia 1.
O nome `VFS` so vale a pena se o contrato realmente virar owner de:
- identificacao de documentos,
- leitura estrutural,
- conteudo resolvido para open files,
- e futura sobreposicao de estado em memoria.
Se a equipe quiser evitar peso terminologico agora, `Option B` e um passo valido.
Mas a direcao arquitetural mais coerente parece ser nomear logo o boundary correto e mantê-lo deliberadamente estreito.
## Resolution
Recommended direction: seguir com **Option D**, com o escopo estrito de `Option C` e o corte funcional limitado ao que o `EditorWorkspace` ja faz hoje.
Fechamento recomendado para a proxima `decision`:
1. o `Code Editor` deve consumir um boundary proprio de `tree + document content`, em vez de instanciar loaders filesystem concretos;
2. nesta etapa, o boundary deve transportar apenas as capacidades que o `EditorWorkspace` ja possui hoje, sem adicionar novas features editoriais;
3. esse boundary deve viver como servico de sessao de projeto do Studio, nao como detalhe de lifecycle do `EditorWorkspace`;
4. esse boundary comeca como `filesystem-backed`, e o Studio passa a tocar o disco atraves do `prometeu-vfs`;
5. `refresh` permanece somente manual, e `watchers` ficam explicitamente fora desta primeira decisao;
6. regras de arquivos, plugins e suporte/não-suporte pertencem ao `prometeu-vfs`; o Studio apenas apresenta o erro ou estado correspondente;
7. o nome/namespace recomendado e criar um novo modulo-base `prometeu-vfs`, deixando `prometeu-lsp` intacto como consumidor superior futuro quando a camada de protocolo existir;
8. a API oficial inicial do `prometeu-vfs` fica concentrada em RPC/comandos/queries; eventos podem existir internamente, mas nao precisam ser publicados nesta wave;
9. a `tree` do `prometeu-vfs` deve ser estrutural e de dados apenas; tree visual, estado de apresentacao e navigator chrome continuam no Studio;
10. o `Project Navigator` consome uma entidade-arvore do projeto inteiro, sem ver filesystem diretamente, mas pode solicitar atualizacoes pontuais;
11. o boundary nasce como primitive util para `studio`; hoje o editor consome, e futuramente o `prometeu-lsp` pode consumir tambem;
12. o snapshot do `prometeu-vfs` cobre apenas conteudo do projeto;
13. packer, assets e demais dominios continuam com ownership proprio e fora desse boundary, salvo decisao posterior explicita.
Next step suggestion: converter esta agenda em uma `decision` que feche o nome do modulo-base, seu lifecycle de sessao de projeto no Studio, o contrato minimo inicial de `tree/document/RPC`, e a linha exata entre `workspace shell`, `prometeu-vfs` e um futuro `prometeu-lsp`.