prometeu-runtime/discussion/workflow/agendas/AGD-0034-agenda-systemos-domain-facades.md
2026-05-15 06:25:04 +01:00

11 KiB

id ticket title status created resolved decision tags
AGD-0034 system-os-domain-facades Agenda - SystemOS Domain Facades accepted 2026-05-15 2026-05-15 DEC-0026
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:

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:

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:

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:

os.lifecycle().suspend_task(...)
os.fs().mount(...)
os.window().set_focus(...)

Ou, se o design permitir sem duplicar ownership:

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:

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 é:

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:

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:

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:

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

  • 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()
  • 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
  • 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.
  • tick_vm e initialize_vm devem ficar temporariamente na raiz, ou já entrar em os.vm()? isso, os.vm().
  • 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.
  • 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:

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.