--- id: AGD-0034 ticket: system-os-domain-facades title: Agenda - SystemOS Domain Facades status: accepted created: 2026-05-15 resolved: 2026-05-15 decision: DEC-0026 tags: [runtime, os, services, api-surface, lifecycle, fs] --- # Agenda - SystemOS Domain Facades ## Contexto Depois de `DEC-0024` e `DEC-0025`, `SystemOS` passou a concentrar ownership e coordenação de vários domínios do Prometeu OS: ```text SystemOS vm_runtime process_manager task_manager window_manager log_service fs / fs_state / open_files / next_handle memcard lifecycle methods VM initialize/tick helpers ``` Essa concentração é correta do ponto de vista de ownership: o OS deve ser dono ou mediador dos serviços do console. O problema agora é a superfície pública do root. Se tudo fica como `os.bla()`, `os.campo.bla()` ou campos públicos soltos, o `SystemOS` vira um objeto largo demais e deixa de comunicar domínio. A intenção proposta é separar a superfície em compartimentos: ```text os.lifecycle().suspend_task(...) os.lifecycle().resume_task(...) os.lifecycle().crash_task(...) os.sessions().create_vm_game_task(...) os.sessions().create_vm_shell_task(...) os.sessions().create_native_shell_task(...) os.vm().initialize(...) os.vm().tick(...) os.fs().mount(...) os.fs().open(...) os.fs().read(...) os.fs().write(...) os.fs().close(...) os.window().add_window(...) os.window().set_focus(...) os.window().focused_window(...) os.window().close_window(...) ``` Logging pode continuar na raiz como operação transversal: ```text os.log(...) ``` ## Problema O `SystemOS` está crescendo wild na raiz. Isso cria alguns riscos: - novos domínios tendem a adicionar mais métodos diretamente em `SystemOS`; - lifecycle, filesystem, window, VM runtime e memcard competem pela mesma superfície; - testes e firmware continuam alcançando managers internos diretamente; - fica difícil distinguir API semântica de OS de detalhe interno de serviço; - a raiz pública pode virar uma coleção de campos públicos em vez de uma interface de sistema. O ponto importante: não queremos desfazer o ownership do `SystemOS`. Queremos compartimentalizar o acesso. ## Pontos Criticos - `SystemOS` deve continuar sendo o boundary de ownership e coordenação. - Facades não devem virar owners independentes que duplicam estado. - A raiz do OS deve ficar pequena e expressiva. - Lifecycle deve continuar coordenando `TaskState` e `ProcessState` junto. - Filesystem tem estado composto (`VirtualFS`, `FsState`, `open_files`, `next_handle`) e por isso se beneficia de uma facade própria. - Window management já é serviço do OS, mas `PrometeuHub` e firmware ainda acessam `os.window_manager` diretamente. - VM runtime talvez também precise de facade ou área própria, mas isso pode ser uma etapa posterior para não misturar com lifecycle/fs. - O formato da facade precisa respeitar borrow rules em Rust; campos públicos simples podem não ser viáveis quando uma operação precisa de múltiplos campos internos do `SystemOS`. ## Opcoes ### Opcao A - Manter tudo na raiz do SystemOS **Abordagem:** Continuar adicionando métodos e campos diretamente em `SystemOS`. **Vantagens:** - menor mudança imediata; - callsites simples; - menos tipos auxiliares; - evita atrito com borrow checker. **Custos / Riscos:** - a raiz continua crescendo; - domínios ficam misturados; - incentiva acesso direto a managers internos; - torna mais difícil explicar a API do OS; - cada nova capability aumenta a pressão no mesmo arquivo e no mesmo objeto. **Manutenibilidade:** Fraca no médio prazo. ### Opcao B - Criar facades de domínio em torno do SystemOS **Abordagem:** Criar facades estreitas por domínio, expostas como acesso semântico: ```text os.lifecycle().suspend_task(...) os.fs().mount(...) os.window().set_focus(...) ``` Ou, se o design permitir sem duplicar ownership: ```text os.lifecycle.suspend_task(...) os.fs.mount(...) os.window.set_focus(...) ``` As facades seriam views/handles sobre os campos internos do `SystemOS`, não owners independentes. **Vantagens:** - deixa a raiz do OS menor; - agrupa API por domínio; - torna mais claro o que é lifecycle, fs, window, memcard e VM; - ajuda a esconder managers internos; - reduz a chance de firmware coordenar detalhes por fora. **Custos / Riscos:** - exige decidir padrão de borrowing; - pode adicionar tipos pequenos e boilerplate; - `os.lifecycle.bla()` como campo direto pode ser difícil se a facade precisar acessar `task_manager` e `process_manager` que vivem no mesmo `SystemOS`; - talvez precise começar com métodos `os.lifecycle()` em vez de campos públicos. **Manutenibilidade:** Forte se as facades forem views estreitas e não novos owners. ### Opcao C - Criar services owners independentes dentro do SystemOS **Abordagem:** Mover estado e lógica para structs owned diretamente: ```text SystemOS lifecycle: LifecycleService fs: FileSystemService window: WindowService ``` Cada service seria owner do seu próprio estado ou de parte dele. **Vantagens:** - aproxima o shape desejado `os.lifecycle.bla()`; - reduz métodos no root; - pode simplificar alguns domínios autocontidos. **Custos / Riscos:** - lifecycle precisa coordenar task/process, então ownership separado pode criar borrow/coordenação mais difícil; - filesystem hoje cruza VM syscall state, `VirtualFS`, `FsState`, handles e logging; - pode reabrir decisões de ownership que acabaram de estabilizar; - risco de mover estado cedo demais para caber numa estética de API. **Manutenibilidade:** Boa para domínios autocontidos, arriscada para lifecycle neste momento. ## Sugestao / Recomendacao A direção recomendada é **Opção B: facades de domínio como views estreitas sobre o `SystemOS`**. O corte recomendado é: ```text SystemOS lifecycle() set_foreground_task suspend_task resume_task close_task crash_task sessions() create_vm_game_task create_vm_shell_task create_native_shell_task vm() initialize tick fs() mount open read write close window() add_window set_focus focused_window close_window log(...) ``` E evitar que a raiz acumule: ```text suspend_task resume_task close_task crash_task mount_fs initialize_vm tick_vm create_vm_game_task create_vm_shell_task create_native_shell_task window_manager direto task_manager direto process_manager direto vm_runtime direto fs direto memcard direto ``` Para Rust, o primeiro corte provavelmente deve usar métodos de acesso que retornam views: ```rust os.lifecycle().suspend_task(task_id) os.fs().mount(backend) os.window().set_focus(window_id) ``` Isso é menos bonito que campo direto, mas evita congelar ownership errado. Se mais tarde algum domínio puder virar service owner real, podemos migrar para campo direto sem mudar a semântica. Logging pode permanecer na raiz: ```rust os.log(...) ``` Motivo: logging é transversal, curto, usado por várias etapas do firmware, e não carrega sozinho uma política complexa de estado. ## Perguntas em Aberto - [x] Queremos a sintaxe ideal `os.lifecycle.bla()` mesmo que isso force services owners reais, ou aceitamos `os.lifecycle().bla()` como primeira forma borrow-friendly? quando escrevi os.lifecycle.bla() eu queria mesmo era os.lifecycle().bla() - [x] Quais domínios entram no primeiro corte: só `lifecycle` e `fs`, ou também `window`? nao precisamos criar nada, mas lifecycle, fs, window e vm sao easy wins no meu ponto de vista - [x] `create_vm_game_task` e `create_vm_shell_task` pertencem a `os.lifecycle()`, a `os.processes()/os.tasks()`, ou a um futuro domínio `os.apps()/os.sessions()`? vamos de os.session() para esses. - [x] `tick_vm` e `initialize_vm` devem ficar temporariamente na raiz, ou já entrar em `os.vm()`? isso, os.vm(). - [x] Campos como `task_manager`, `process_manager`, `window_manager`, `vm_runtime`, `fs`, `memcard` devem deixar de ser públicos no mesmo corte ou em planos graduais? eu nao os deixaria publicos desde jah, isso forca a politica de facades dentro de system os. - [x] Como preservar testes sem criar APIs públicas só para inspeção? Testes devem ser feitos nos subdomínios; SystemOS só testa composição e coordenação que não pertence isoladamente a um domínio. ## Resolucao Proposta A agenda deve fechar pela **Opção B**. O `SystemOS` continua sendo o owner e boundary de coordenação, mas sua superfície pública deve ser compartimentalizada em facades de domínio. A forma normativa inicial deve ser por métodos que retornam views borrow-friendly: ```rust os.lifecycle().suspend_task(task_id) os.sessions().create_vm_game_task(app_id, title) os.vm().initialize(vm, cartridge) os.fs().mount(backend) os.window().set_focus(window_id) os.log(level, source, tag, msg) ``` A sintaxe com campo direto (`os.lifecycle.suspend_task(...)`) não é requisito deste corte. A intenção semântica é domínio explícito; a forma prática inicial deve respeitar ownership e borrowing em Rust. Domínios do primeiro corte: - `lifecycle()`: lifecycle semântico de task/process. - `sessions()`: criação de tasks/processos de jogo e shell. - `vm()`: inicialização e tick da VM. - `fs()`: filesystem operacional. - `window()`: operações mínimas de janela/foco. - `log(...)`: permanece na raiz como operação transversal. Campos internos como `task_manager`, `process_manager`, `window_manager`, `vm_runtime`, `fs`, `fs_state`, `memcard`, `open_files` e `next_handle` devem deixar de ser públicos já neste corte, salvo se um plan específico demonstrar necessidade temporária de migração. A política desejada é forçar acesso por facades dentro do `SystemOS`. Testes devem migrar para os subdomínios quando estiverem validando comportamento de domínio. `SystemOS` deve testar apenas composição e coordenação que realmente não pertence isoladamente a um domínio. ## Criterio para Encerrar Esta agenda pode virar decisão quando fecharmos: - qual forma de facade será normativa: campo direto, método view, ou service owner; **resolvido: método view borrow-friendly.** - quais domínios entram no primeiro corte; **resolvido: lifecycle, sessions, vm, fs, window e log na raiz.** - quais APIs permanecem no root; **resolvido: `new`/construção e `log(...)`; demais APIs devem migrar para facades.** - se campos internos deixam de ser públicos agora ou em ondas; **resolvido: deixar de ser públicos já no corte, com exceção transitória somente se plan demonstrar necessidade.** - como lifecycle, fs e window serão acessados por firmware, Hub e testes. **resolvido: por facades; testes de domínio nos subdomínios.** ## Proximo Passo Esta agenda está pronta para decisão normativa se a resolução proposta for aceita.