--- 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`.