# Published Entrypoint, Synthetic Wrapper, and FRAME_RET Ownership Agenda ## Status Open ## Parent Agenda This agenda derives from: - `19. Globals, Synthetic Module Init, and FRAME_RET Agenda` Expected fixed inputs from previous stages: - `19.1. PBS Globals Surface, Identity, and Module Boundaries Agenda` - `19.2. PBS Lifecycle Markers, Program Init, and Frame Root Semantics Agenda` ## Purpose Define how PBS lifecycle is published into the executable artifact once globals and lifecycle semantics are already fixed. This agenda must close: - whether the published entrypoint becomes a synthetic wrapper; - the semantic and publication relationship between user `frame()` and the published entrypoint; - the new owner of `FRAME_RET`; - and the contract boundary between source-derived entrypoint discovery, `FrontendSpec`, and cartridge manifest publication. ## Domain Owner `docs/compiler/pbs` Este tema pertence ao domínio PBS porque decide a fronteira entre semântica da linguagem, entrypoint publicado e artefato executável. ## Context Se `frame()` do usuário deixar de ser o callable publicado diretamente, o compiler precisará publicar outro root executável. Isso abre quatro perguntas acopladas: - quem é o entrypoint físico do artefato; - qual callable continua sendo o root lógico do código do usuário; - onde `FRAME_RET` passa a ser emitido; - e como manifest e `FrontendSpec` representam isso sem ambiguidade. Esta agenda existe para fechar esse contrato antes de discutir detalhe de representação de IR. ## Inputs Already Fixed Elsewhere Os seguintes inputs devem ser tratados como fixos aqui: - o modelo de globals vindo de `19.1`; - o modelo de lifecycle e markers vindo de `19.2`; - `FRAME_RET` continua significando fim do frame lógico; - o runtime continua esperando um entrypoint published por frame. ## Decisions To Produce Esta agenda deve produzir direção suficiente para fechar: 1. se o published entrypoint é um wrapper sintético; 2. qual é a relação entre `frame()` do usuário e esse wrapper; 3. onde `FRAME_RET` passa a viver; 4. como a autoridade de entrypoint sai de `FrontendSpec` e passa ao compiler PBS; 5. como o protocolo de runtime/manifest representa esse entrypoint. ## Core Questions 1. O compiler deve publicar um wrapper sintético como entrypoint real? 2. `frame()` do usuário deixa de ser o callable publicado e passa a ser apenas root lógico interno? 3. `FRAME_RET` deve ser emitido no wrapper, não mais no callable do usuário? 4. O compiler PBS deve se tornar a única autoridade para definir o entrypoint publicado? 5. O wrapper sintético deve ocupar protocolarmente o entrypoint físico `0`? 6. O campo `entrypoint` deve deixar de existir no `manifest.json` como estado alvo do protocolo? 7. Existe algum caso em que o wrapper não seja necessário depois de `19.2`? ## Options ### Option A Publicar um wrapper sintético como entrypoint físico, tratar `frame()` do usuário como root lógico interno, mover `FRAME_RET` para o wrapper, tornar o compiler PBS a autoridade exclusiva de entrypoint e fixar protocolarmente o entrypoint físico em `0`. ### Option B Manter `frame()` do usuário como entrypoint publicado e tentar acoplar boot/lifecycle diretamente nele. ### Option C Publicar wrapper sintético, mas manter `entrypoint` no manifest como autoridade nominal paralela. ## Tradeoffs ### Option A - Prós: - separa lifecycle publicado do callable do usuário; - acomoda boot one-shot de forma limpa; - preserva o significado de `FRAME_RET` com owner mais correto. - alinha melhor o protocolo físico do artefato com a política já existente de `func_id = 0` como entrypoint; - remove autoridade duplicada entre compiler, manifest e `FrontendSpec`. - Contras: - exige trabalho claro de migração em manifest, runtime e `FrontendSpec`; - torna a relação lógico/físico explicitamente dupla. ### Option B - Prós: - preserva a superfície atual de publicação. - Contras: - mistura responsabilidades demais no callable do usuário; - enfraquece a clareza do lifecycle. ### Option C - Prós: - parece reduzir custo de transição imediata. - Contras: - mantém duas autoridades para entrypoint; - cria dívida documental e de runtime desnecessária; - enfraquece a ideia de entrypoint como protocolo fixo do artefato. ## Recommendation Seguir com a **Option A**. ## Current Direction Os pontos abaixo já podem ser tratados como direção fechada desta agenda, salvo objeção nova forte: 1. o compiler deve publicar um wrapper sintético como entrypoint físico real; 2. esse wrapper deve conter: - boot one-shot, - os inits necessários apenas uma vez, - a chamada ao `frame()` do usuário, - e o `FRAME_RET` final; 3. `frame()` anotado com `[Frame]` permanece como root lógico do usuário; 4. o wrapper sintético é o root físico publicado; 5. `FRAME_RET` sai do final do `frame()` do usuário e passa a existir no wrapper; 6. `FrontendSpec` perde autoridade para referenciar quem é o entrypoint; 7. a autoridade de entrypoint fica outorgada exclusivamente ao compiler PBS; 8. o wrapper sintético deve ser compilado no entrypoint físico `0`; 9. o estado alvo do protocolo deve remover `entrypoint` do `manifest.json`; 10. o runtime/loader deve tratar o entrypoint como protocolo fixo do artefato, não como metadado nominal configurável no manifest. ## Manifest and Runtime Direction Esta agenda também já aponta para a seguinte direção de contrato: 1. o campo `entrypoint` deve deixar de existir no `manifest.json` como estado final do protocolo; 2. o runtime deve assumir protocolarmente o entrypoint físico `0`; 3. o compiler garante que esse índice `0` pertence ao wrapper sintético publicado; 4. export nominal do callable deixa de ser a autoridade de boot; 5. qualquer compatibilidade temporária com manifest nominal deve ser tratada apenas como transição, não como contrato final desejado. ## Exports Boundary Esta agenda também fecha a seguinte separação: 1. exports nominais de funções podem continuar existindo no artefato; 2. esses exports deixam de ser usados como autoridade de loader/boot; 3. boot passa a depender exclusivamente do entrypoint físico `0` publicado pelo compiler; 4. exports nominais permanecem apenas como superfície útil para tooling, debug, introspection e casos correlatos. ## Remaining Open Points Com a direção acima, os pontos que ainda pedem fechamento real nesta agenda ficam reduzidos a: 1. a forma de propagação normativa dessa mudança para specs gerais de bytecode, lowering e cartridge contract. ## Runtime Propagation Esta agenda também deve referenciar explicitamente a discussão correspondente no domínio runtime: - `../runtime/docs/runtime/agendas/025-cartridge-manifest-entrypoint-removal-and-runtime-protocol.md` Direção fechada desta agenda: 1. não há linha de compatibilidade desejada como estado-alvo; 2. a remoção de `entrypoint` do runtime deve ser executada em prioridade alinhada ao compiler; 3. a agenda de runtime é o owner da discussão operacional de loader/VM/manifest no outro domínio. ## Expected Spec Material Se esta agenda fechar, a propagação esperada atinge pelo menos: - `9. Dynamic Semantics Specification.md` - `13. Lowering IRBackend Specification.md` - `7. Cartridge Manifest and Runtime Capabilities Specification.md` - `12. Diagnostics Specification.md` ## Non-Goals Esta agenda não deve: 1. escolher o encoding exato do wrapper no IR; 2. definir estrutura detalhada de module init lowering; 3. escrever fixtures completos de conformance. ## Next Step Depois de fechar esta agenda, abrir ou aprofundar: - `19.4. Globals and Lifecycle Lowering to IRBackend/IRVM Agenda`