Studio with hint decorators

This commit is contained in:
bQUARKz 2026-04-03 11:20:08 +01:00
parent f368ed94d2
commit e8ec9973cd
Signed by: bquarkz
SSH Key Fingerprint: SHA256:Z7dgqoglWwoK6j6u4QC87OveEq74WOhFN+gitsxtkf8
4 changed files with 306 additions and 1 deletions

View File

@ -1,4 +1,4 @@
{"type":"meta","next_id":{"DSC":17,"AGD":18,"DEC":15,"PLN":33,"LSN":31,"CLSN":1}} {"type":"meta","next_id":{"DSC":18,"AGD":19,"DEC":16,"PLN":37,"LSN":31,"CLSN":1}}
{"type":"discussion","id":"DSC-0001","status":"done","ticket":"studio-docs-import","title":"Import docs/studio into discussion-framework artifacts","created_at":"2026-03-26","updated_at":"2026-03-26","tags":["studio","migration","discussion-framework","docs-import"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0001","file":"discussion/lessons/DSC-0001-studio-docs-import/LSN-0001-assets-workspace-execution-wave-legacy.md","status":"done","created_at":"2026-03-26","updated_at":"2026-03-26"},{"id":"LSN-0002","file":"discussion/lessons/DSC-0001-studio-docs-import/LSN-0002-bank-composition-editor-legacy.md","status":"done","created_at":"2026-03-26","updated_at":"2026-03-26"},{"id":"LSN-0003","file":"discussion/lessons/DSC-0001-studio-docs-import/LSN-0003-mental-model-asset-mutations-legacy.md","status":"done","created_at":"2026-03-26","updated_at":"2026-03-26"},{"id":"LSN-0004","file":"discussion/lessons/DSC-0001-studio-docs-import/LSN-0004-mental-model-assets-workspace-legacy.md","status":"done","created_at":"2026-03-26","updated_at":"2026-03-26"},{"id":"LSN-0005","file":"discussion/lessons/DSC-0001-studio-docs-import/LSN-0005-mental-model-studio-events-and-components-legacy.md","status":"done","created_at":"2026-03-26","updated_at":"2026-03-26"},{"id":"LSN-0006","file":"discussion/lessons/DSC-0001-studio-docs-import/LSN-0006-mental-model-studio-shell-legacy.md","status":"done","created_at":"2026-03-26","updated_at":"2026-03-26"},{"id":"LSN-0007","file":"discussion/lessons/DSC-0001-studio-docs-import/LSN-0007-pack-wizard-shell-legacy.md","status":"done","created_at":"2026-03-26","updated_at":"2026-03-26"},{"id":"LSN-0008","file":"discussion/lessons/DSC-0001-studio-docs-import/LSN-0008-project-scoped-state-and-activity-legacy.md","status":"done","created_at":"2026-03-26","updated_at":"2026-03-26"},{"id":"LSN-0016","file":"discussion/lessons/DSC-0001-studio-docs-import/LSN-0016-studio-docs-import-pattern.md","status":"done","created_at":"2026-03-26","updated_at":"2026-03-26"}]} {"type":"discussion","id":"DSC-0001","status":"done","ticket":"studio-docs-import","title":"Import docs/studio into discussion-framework artifacts","created_at":"2026-03-26","updated_at":"2026-03-26","tags":["studio","migration","discussion-framework","docs-import"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0001","file":"discussion/lessons/DSC-0001-studio-docs-import/LSN-0001-assets-workspace-execution-wave-legacy.md","status":"done","created_at":"2026-03-26","updated_at":"2026-03-26"},{"id":"LSN-0002","file":"discussion/lessons/DSC-0001-studio-docs-import/LSN-0002-bank-composition-editor-legacy.md","status":"done","created_at":"2026-03-26","updated_at":"2026-03-26"},{"id":"LSN-0003","file":"discussion/lessons/DSC-0001-studio-docs-import/LSN-0003-mental-model-asset-mutations-legacy.md","status":"done","created_at":"2026-03-26","updated_at":"2026-03-26"},{"id":"LSN-0004","file":"discussion/lessons/DSC-0001-studio-docs-import/LSN-0004-mental-model-assets-workspace-legacy.md","status":"done","created_at":"2026-03-26","updated_at":"2026-03-26"},{"id":"LSN-0005","file":"discussion/lessons/DSC-0001-studio-docs-import/LSN-0005-mental-model-studio-events-and-components-legacy.md","status":"done","created_at":"2026-03-26","updated_at":"2026-03-26"},{"id":"LSN-0006","file":"discussion/lessons/DSC-0001-studio-docs-import/LSN-0006-mental-model-studio-shell-legacy.md","status":"done","created_at":"2026-03-26","updated_at":"2026-03-26"},{"id":"LSN-0007","file":"discussion/lessons/DSC-0001-studio-docs-import/LSN-0007-pack-wizard-shell-legacy.md","status":"done","created_at":"2026-03-26","updated_at":"2026-03-26"},{"id":"LSN-0008","file":"discussion/lessons/DSC-0001-studio-docs-import/LSN-0008-project-scoped-state-and-activity-legacy.md","status":"done","created_at":"2026-03-26","updated_at":"2026-03-26"},{"id":"LSN-0016","file":"discussion/lessons/DSC-0001-studio-docs-import/LSN-0016-studio-docs-import-pattern.md","status":"done","created_at":"2026-03-26","updated_at":"2026-03-26"}]}
{"type":"discussion","id":"DSC-0002","status":"open","ticket":"palette-management-in-studio","title":"Palette Management in Studio","created_at":"2026-03-26","updated_at":"2026-03-26","tags":["studio","legacy-import","palette-management","tile-bank","packer-boundary"],"agendas":[{"id":"AGD-0002","file":"AGD-0002-palette-management-in-studio.md","status":"open","created_at":"2026-03-26","updated_at":"2026-03-26"}],"decisions":[],"plans":[],"lessons":[]} {"type":"discussion","id":"DSC-0002","status":"open","ticket":"palette-management-in-studio","title":"Palette Management in Studio","created_at":"2026-03-26","updated_at":"2026-03-26","tags":["studio","legacy-import","palette-management","tile-bank","packer-boundary"],"agendas":[{"id":"AGD-0002","file":"AGD-0002-palette-management-in-studio.md","status":"open","created_at":"2026-03-26","updated_at":"2026-03-26"}],"decisions":[],"plans":[],"lessons":[]}
{"type":"discussion","id":"DSC-0003","status":"done","ticket":"packer-docs-import","title":"Import docs/packer into discussion-framework artifacts","created_at":"2026-03-26","updated_at":"2026-03-26","tags":["packer","migration","discussion-framework","docs-import"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0009","file":"discussion/lessons/DSC-0003-packer-docs-import/LSN-0009-mental-model-packer-legacy.md","status":"done","created_at":"2026-03-26","updated_at":"2026-03-26"},{"id":"LSN-0010","file":"discussion/lessons/DSC-0003-packer-docs-import/LSN-0010-asset-identity-and-runtime-contract-legacy.md","status":"done","created_at":"2026-03-26","updated_at":"2026-03-26"},{"id":"LSN-0011","file":"discussion/lessons/DSC-0003-packer-docs-import/LSN-0011-foundations-workspace-runtime-and-build-legacy.md","status":"done","created_at":"2026-03-26","updated_at":"2026-03-26"},{"id":"LSN-0012","file":"discussion/lessons/DSC-0003-packer-docs-import/LSN-0012-runtime-ownership-and-studio-boundary-legacy.md","status":"done","created_at":"2026-03-26","updated_at":"2026-03-26"},{"id":"LSN-0013","file":"discussion/lessons/DSC-0003-packer-docs-import/LSN-0013-metadata-convergence-and-runtime-sink-legacy.md","status":"done","created_at":"2026-03-26","updated_at":"2026-03-26"},{"id":"LSN-0014","file":"discussion/lessons/DSC-0003-packer-docs-import/LSN-0014-pack-wizard-summary-validation-and-pack-execution-legacy.md","status":"done","created_at":"2026-03-26","updated_at":"2026-03-26"},{"id":"LSN-0015","file":"discussion/lessons/DSC-0003-packer-docs-import/LSN-0015-tile-bank-packing-contract-legacy.md","status":"done","created_at":"2026-03-26","updated_at":"2026-03-26"},{"id":"LSN-0017","file":"discussion/lessons/DSC-0003-packer-docs-import/LSN-0017-packer-docs-import-pattern.md","status":"done","created_at":"2026-03-26","updated_at":"2026-03-26"}]} {"type":"discussion","id":"DSC-0003","status":"done","ticket":"packer-docs-import","title":"Import docs/packer into discussion-framework artifacts","created_at":"2026-03-26","updated_at":"2026-03-26","tags":["packer","migration","discussion-framework","docs-import"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0009","file":"discussion/lessons/DSC-0003-packer-docs-import/LSN-0009-mental-model-packer-legacy.md","status":"done","created_at":"2026-03-26","updated_at":"2026-03-26"},{"id":"LSN-0010","file":"discussion/lessons/DSC-0003-packer-docs-import/LSN-0010-asset-identity-and-runtime-contract-legacy.md","status":"done","created_at":"2026-03-26","updated_at":"2026-03-26"},{"id":"LSN-0011","file":"discussion/lessons/DSC-0003-packer-docs-import/LSN-0011-foundations-workspace-runtime-and-build-legacy.md","status":"done","created_at":"2026-03-26","updated_at":"2026-03-26"},{"id":"LSN-0012","file":"discussion/lessons/DSC-0003-packer-docs-import/LSN-0012-runtime-ownership-and-studio-boundary-legacy.md","status":"done","created_at":"2026-03-26","updated_at":"2026-03-26"},{"id":"LSN-0013","file":"discussion/lessons/DSC-0003-packer-docs-import/LSN-0013-metadata-convergence-and-runtime-sink-legacy.md","status":"done","created_at":"2026-03-26","updated_at":"2026-03-26"},{"id":"LSN-0014","file":"discussion/lessons/DSC-0003-packer-docs-import/LSN-0014-pack-wizard-summary-validation-and-pack-execution-legacy.md","status":"done","created_at":"2026-03-26","updated_at":"2026-03-26"},{"id":"LSN-0015","file":"discussion/lessons/DSC-0003-packer-docs-import/LSN-0015-tile-bank-packing-contract-legacy.md","status":"done","created_at":"2026-03-26","updated_at":"2026-03-26"},{"id":"LSN-0017","file":"discussion/lessons/DSC-0003-packer-docs-import/LSN-0017-packer-docs-import-pattern.md","status":"done","created_at":"2026-03-26","updated_at":"2026-03-26"}]}
@ -15,3 +15,4 @@
{"type":"discussion","id":"DSC-0014","status":"done","ticket":"studio-frontend-owned-semantic-editor-presentation","title":"Definir ownership do schema visual semantico do editor por frontend","created_at":"2026-04-02","updated_at":"2026-04-02","tags":["studio","editor","frontend","presentation","semantic-highlighting","compiler","pbs"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0029","file":"discussion/lessons/DSC-0014-studio-frontend-owned-semantic-editor-presentation/LSN-0029-frontend-owned-semantic-presentation-descriptor-and-host-consumption.md","status":"done","created_at":"2026-04-02","updated_at":"2026-04-02"}]} {"type":"discussion","id":"DSC-0014","status":"done","ticket":"studio-frontend-owned-semantic-editor-presentation","title":"Definir ownership do schema visual semantico do editor por frontend","created_at":"2026-04-02","updated_at":"2026-04-02","tags":["studio","editor","frontend","presentation","semantic-highlighting","compiler","pbs"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0029","file":"discussion/lessons/DSC-0014-studio-frontend-owned-semantic-editor-presentation/LSN-0029-frontend-owned-semantic-presentation-descriptor-and-host-consumption.md","status":"done","created_at":"2026-04-02","updated_at":"2026-04-02"}]}
{"type":"discussion","id":"DSC-0015","status":"done","ticket":"pbs-service-facade-reserved-metadata","title":"SDK Service Bodies Calling Builtin/Intrinsic Proxies as Ordinary PBS Code","created_at":"2026-04-03","updated_at":"2026-04-03","tags":["compiler","pbs","sdk","stdlib","lowering","service","intrinsic","sdk-interface"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0030","file":"discussion/lessons/DSC-0015-pbs-service-facade-reserved-metadata/LSN-0030-sdk-service-bodies-over-private-reserved-proxies.md","status":"done","created_at":"2026-04-03","updated_at":"2026-04-03"}]} {"type":"discussion","id":"DSC-0015","status":"done","ticket":"pbs-service-facade-reserved-metadata","title":"SDK Service Bodies Calling Builtin/Intrinsic Proxies as Ordinary PBS Code","created_at":"2026-04-03","updated_at":"2026-04-03","tags":["compiler","pbs","sdk","stdlib","lowering","service","intrinsic","sdk-interface"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0030","file":"discussion/lessons/DSC-0015-pbs-service-facade-reserved-metadata/LSN-0030-sdk-service-bodies-over-private-reserved-proxies.md","status":"done","created_at":"2026-04-03","updated_at":"2026-04-03"}]}
{"type":"discussion","id":"DSC-0016","status":"open","ticket":"studio-editor-scope-guides-and-brace-anchoring","title":"Scope Guides do Code Editor com ancoragem exata em braces e destaque do escopo ativo","created_at":"2026-04-03","updated_at":"2026-04-03","tags":["studio","editor","scope-guides","braces","semantic-read","frontend-contract"],"agendas":[{"id":"AGD-0017","file":"AGD-0017-studio-editor-scope-guides-and-brace-anchoring.md","status":"accepted","created_at":"2026-04-03","updated_at":"2026-04-03"}],"decisions":[{"id":"DEC-0014","file":"DEC-0014-studio-editor-active-scope-and-structural-anchors.md","status":"accepted","created_at":"2026-04-03","updated_at":"2026-04-03"}],"plans":[{"id":"PLN-0030","file":"PLN-0030-studio-active-container-and-active-scope-gutter-wave-1.md","status":"done","created_at":"2026-04-03","updated_at":"2026-04-03"},{"id":"PLN-0031","file":"PLN-0031-studio-structural-anchor-semantic-surface-specification.md","status":"done","created_at":"2026-04-03","updated_at":"2026-04-03"},{"id":"PLN-0032","file":"PLN-0032-frontend-structural-anchor-payloads-and-anchor-aware-tests.md","status":"done","created_at":"2026-04-03","updated_at":"2026-04-03"}],"lessons":[]} {"type":"discussion","id":"DSC-0016","status":"open","ticket":"studio-editor-scope-guides-and-brace-anchoring","title":"Scope Guides do Code Editor com ancoragem exata em braces e destaque do escopo ativo","created_at":"2026-04-03","updated_at":"2026-04-03","tags":["studio","editor","scope-guides","braces","semantic-read","frontend-contract"],"agendas":[{"id":"AGD-0017","file":"AGD-0017-studio-editor-scope-guides-and-brace-anchoring.md","status":"accepted","created_at":"2026-04-03","updated_at":"2026-04-03"}],"decisions":[{"id":"DEC-0014","file":"DEC-0014-studio-editor-active-scope-and-structural-anchors.md","status":"accepted","created_at":"2026-04-03","updated_at":"2026-04-03"}],"plans":[{"id":"PLN-0030","file":"PLN-0030-studio-active-container-and-active-scope-gutter-wave-1.md","status":"done","created_at":"2026-04-03","updated_at":"2026-04-03"},{"id":"PLN-0031","file":"PLN-0031-studio-structural-anchor-semantic-surface-specification.md","status":"done","created_at":"2026-04-03","updated_at":"2026-04-03"},{"id":"PLN-0032","file":"PLN-0032-frontend-structural-anchor-payloads-and-anchor-aware-tests.md","status":"done","created_at":"2026-04-03","updated_at":"2026-04-03"}],"lessons":[]}
{"type":"discussion","id":"DSC-0017","status":"open","ticket":"studio-editor-inline-type-hints-for-let-bindings","title":"Inline Type Hints for Let Bindings in the Studio Editor","created_at":"2026-04-03","updated_at":"2026-04-03","tags":["studio","editor","inline-hints","inlay-hints","lsp","pbs","type-inference"],"agendas":[{"id":"AGD-0018","file":"AGD-0018-studio-editor-inline-type-hints-for-let-bindings.md","status":"accepted","created_at":"2026-04-03","updated_at":"2026-04-03"}],"decisions":[{"id":"DEC-0015","file":"DEC-0015-studio-editor-inline-type-hints-contract-and-rendering-model.md","status":"accepted","created_at":"2026-04-03","updated_at":"2026-04-03","ref_agenda":"AGD-0018"}],"plans":[{"id":"PLN-0033","file":"PLN-0033-inline-hint-spec-and-contract-propagation.md","status":"open","created_at":"2026-04-03","updated_at":"2026-04-03","ref_decisions":["DEC-0015"]},{"id":"PLN-0034","file":"PLN-0034-lsp-inline-hint-transport-contract.md","status":"open","created_at":"2026-04-03","updated_at":"2026-04-03","ref_decisions":["DEC-0015"]},{"id":"PLN-0035","file":"PLN-0035-pbs-inline-type-hint-payload-production.md","status":"open","created_at":"2026-04-03","updated_at":"2026-04-03","ref_decisions":["DEC-0015"]},{"id":"PLN-0036","file":"PLN-0036-studio-inline-hint-rendering-and-rollout.md","status":"open","created_at":"2026-04-03","updated_at":"2026-04-03","ref_decisions":["DEC-0015"]}],"lessons":[]}

View File

@ -0,0 +1,112 @@
---
id: AGD-0018
ticket: studio-editor-inline-type-hints-for-let-bindings
title: Inline Type Hints for Let Bindings in the Studio Editor
status: accepted
created: 2026-04-03
resolved: 2026-04-03
decision: DEC-0015
tags: [studio, editor, inline-hints, inlay-hints, lsp, pbs, type-inference]
---
## Pain
O Code Editor do Studio já mostra semantic highlighting e structure guides, mas ainda não ajuda o usuário a visualizar tipos inferidos localmente em bindings como `let value = expr;`.
Isso cria duas fricções:
- o usuário perde feedback rápido sobre o tipo efetivo inferido pelo frontend;
- o editor fica atrás de IDEs que mostram hints não textuais inline para reduzir ambiguidade sem poluir o source.
## Context
- O editor atual usa `CodeArea` do RichTextFX com `StyleSpans`, gutter graphics e semantic read vindo do LSP.
- O frontend PBS já infere o tipo de `let` durante a análise de fluxo, mas esse dado não é publicado como uma surface explícita consumível pelo editor.
- O Studio hoje não possui uma camada de rendering inline equivalente a inlay hints do IntelliJ.
- O repositório já adotou a direção de presentation frontend-owned para semantic rendering, mas inlay hints de tipo parecem tocar uma fronteira diferente: parte do dado nasce no frontend/LSP, parte do rendering nasce no host editor.
## Open Questions
- [x] Qual deve ser o owner do payload do hint: frontend puro, LSP derivado, ou Studio como consumer de uma surface semântica padronizada?
Resposta: o frontend define a surface e o payload; o LSP fixa e transporta o contrato; o Studio renderiza.
- [x] O hint deve ser limitado a `let` com tipo omitido ou também cobrir `const`, parâmetros inferidos futuros e outros binders?
Resposta: quem decide quais hints existem é o frontend; se o hint vier no contrato, o Studio imprime.
- [x] O rendering deve ser inline real no fluxo do texto ou uma aproximação visual menos invasiva numa primeira wave?
Resposta: o estado final obrigatório da feature é inline real; aproximação visual só é aceitável como etapa transitória.
- [x] O hint precisa participar de hit testing, seleção, caret navigation e copy/paste, ou deve ser estritamente decorativo?
Resposta: o hint é totalmente decorativo.
- [x] Em caso de erro parcial de análise, o editor deve manter hints estáveis dos spans válidos ou desligar hints do documento?
Resposta: manter hints estáveis dos spans válidos.
## Options
### Option A - LSP Inlay Hints + Inline Rendering Real no Editor
- **Approach:** adicionar uma surface explícita de inlay hints no LSP para bindings `let` e evoluir o Studio para renderização inline não textual no fluxo do editor.
- **Pro:** modelo mais correto, escalável e alinhado com a UX esperada de IDE.
- **Con:** exige mudança estrutural maior no editor, possivelmente acima do que `CodeArea + StyleSpans` entrega nativamente.
- **Maintainability:** boa no longo prazo se virar um primitive reutilizável para hints, parameter names e outras decorações inline.
### Option B - LSP Inlay Hints + Overlay Visual Aproximado na Primeira Wave
- **Approach:** publicar hints no LSP, mas renderizar numa camada visual acoplada ao editor sem inserir segmentos inline reais no documento na primeira etapa.
- **Pro:** destrava valor ao usuário mais cedo e reduz risco inicial na infraestrutura do editor.
- **Con:** pode divergir do comportamento esperado de caret, wrapping e alinhamento fino; corre risco de parecer remendo se ficar permanente.
- **Maintainability:** aceitável apenas se explicitamente tratada como wave transitória rumo a rendering inline real.
### Option C - Não criar inlay hints; usar apenas hover/inspector
- **Approach:** expor tipo inferido via hover, status bar ou helper panel em vez de hint persistente na linha.
- **Pro:** implementação menor e compatível com a arquitetura atual.
- **Con:** não resolve o objetivo principal de feedback contínuo e local; perde ergonomia frente ao benchmark citado.
- **Maintainability:** simples, mas funcionalmente insuficiente para a dor descrita.
## Discussion
O ponto crítico não é só “mostrar texto cinza depois do nome”. A decisão precisa fechar três contratos:
1. contrato de dados:
o frontend/LSP precisa publicar um hint estável com anchor, conteúdo textual e política de exibição;
2. contrato de rendering:
o Studio precisa decidir se quer suportar uma primitive geral de adornos inline ou apenas uma solução pontual para `let`;
3. contrato de interação:
hints não podem contaminar o conteúdo real do documento, mas também não podem quebrar leitura, seleção, scroll ou layout.
O risco de uma solução ad hoc é repetir o problema já visto em outras áreas: valor imediato, mas sem primitive reusável e com alto custo para generalizar depois.
Ao mesmo tempo, exigir inline rendering “perfeito” logo de saída pode atrasar demais uma ergonomia que já tem valor alto para PBS.
Direção já aceita nesta agenda:
1. ownership e contrato:
o frontend oferece a surface de hints, o LSP a transforma em contrato estável de transporte/consumo, e o Studio apenas renderiza;
2. policy de conteúdo:
o Studio não escolhe quais hints existem; se o frontend publicar hint válido no contrato, o host imprime;
3. rendering target:
a feature só fecha corretamente quando o hint for inline real; qualquer overlay aproximado deve ser explicitamente tratado como etapa transitória;
4. interaction model:
hints são decorativos e não alteram texto, seleção, copy/paste ou modelo documental;
5. degradação parcial:
hints válidos devem sobreviver mesmo quando o restante da análise do documento estiver parcialmente degradado.
## Resolution
Recomendação inicial:
- seguir com uma discussion owner de `studio/editor`;
- tratar o problema como uma capability formal de `inlay hints` do editor, não como uma exceção do PBS;
- modelar o contrato como frontend-defined, LSP-enforced/transported, Studio-rendered;
- manter o Studio host-agnostic quanto ao conteúdo do hint;
- aceitar waves transitórias apenas se convergirem explicitamente para inline real;
- preservar hints válidos sob degradação parcial de análise.
Próximo passo sugerido:
- derivar um `plan` que separe explicitamente:
contrato FE/LSP,
primitive de rendering no Studio,
wave transitória opcional,
testes de degradação parcial e comportamento decorativo.

View File

@ -0,0 +1,160 @@
---
id: DEC-0015
ticket: studio-editor-inline-type-hints-for-let-bindings
title: Studio Editor Inline Type Hints Contract and Rendering Model
status: accepted
created: 2026-04-03
accepted: 2026-04-03
agenda: AGD-0018
plans: [PLN-0033, PLN-0034, PLN-0035, PLN-0036]
tags: [studio, editor, inline-hints, inlay-hints, lsp, frontend-contract, type-inference]
---
## Decision
O Studio SHALL support inline type hints as a first-class editor capability rather than as a PBS-only exception.
The ownership model for the capability is normatively locked as follows:
- the frontend MUST define which hints exist, where they anchor, and what semantic payload they carry;
- the LSP MUST define and enforce the transport contract for those hints and MUST transport frontend-produced hint data to the Studio consumer;
- the Studio MUST render transported hints and MUST NOT invent frontend hint content on its own.
The final user-visible form of the feature MUST be real inline rendering inside the editor flow.
Any approximate visual solution MAY be used only as a transitional implementation stage and MUST be explicitly treated as an intermediate rollout step rather than as the final contract.
Inline hints produced under this capability MUST be decorative only.
Inline hints MUST NOT:
- mutate document text;
- participate as document content in copy/paste;
- redefine selection semantics;
- redefine caret movement semantics;
- become part of the persisted file model.
When analysis is partially degraded, the Studio MUST preserve and render hint spans that remain valid under the transported contract rather than disabling all hints for the whole document.
The host policy for what receives hints is frontend-owned.
If a frontend publishes valid hints under the LSP contract, the Studio MUST render them.
If a frontend does not publish a hint for a construct, the Studio MUST NOT synthesize one.
## Rationale
This decision separates semantic ownership from host rendering responsibility in the same disciplined way already adopted for frontend semantic presentation.
The chosen split avoids two failure modes:
1. Studio-owned hint content, which would duplicate frontend semantics and make the editor a second semantic authority;
2. frontend-specific rendering logic inside the Studio host, which would make the editor harder to generalize and maintain.
The decision also prevents a common product regression: shipping an approximate overlay and silently letting it become the permanent implementation.
By locking inline real rendering as the required final state, the repository preserves the intended UX target while still allowing phased execution.
Decorative-only hints keep the document model stable and avoid corrupting editing semantics.
Partial degradation tolerance follows the same operational direction already desired for editor highlighting: valid local semantic signal should survive even when the full-document analysis path is degraded.
## Technical Specification
### 1. Capability Model
The editor hint system MUST be implemented as a host capability named conceptually equivalent to inline or inlay hints.
That capability MUST be host-generic and MUST NOT be modeled as a PBS-only feature.
### 2. Ownership Boundary
Frontend responsibilities:
- define whether a hint exists;
- define the semantic meaning of the hint;
- define the anchor location or anchor span;
- define the payload required for rendering, including display text and any semantic category needed by the contract.
LSP responsibilities:
- define the DTO and transport contract consumed by the Studio;
- validate and transport frontend-produced hint payloads;
- preserve enough anchoring information for deterministic host rendering;
- avoid inventing host-owned semantic meaning not present in frontend-produced hint data.
Studio responsibilities:
- render transported hints;
- apply host styling and layout behavior;
- keep hints visually separate from document text;
- preserve editor document semantics and editing behavior.
### 3. Content Policy
The Studio MUST treat hint presence as frontend-authoritative.
The Studio MUST render valid transported hints regardless of the frontend that produced them.
The Studio MUST NOT hardcode rules such as:
- hint all `let` declarations by host policy;
- suppress frontend-provided hints because the host prefers a different policy;
- create fallback semantic hints not present in the contract.
### 4. Rendering Model
The feature is only considered complete when hints are rendered inline in the editor flow as non-textual host decorations attached to document positions.
An approximate visual stage MAY exist temporarily if needed to de-risk delivery, but:
- it MUST be documented as transitional;
- it MUST NOT redefine the final contract;
- subsequent plans MUST converge explicitly to real inline rendering.
### 5. Interaction Model
Hints are decorative only.
Therefore the implementation MUST ensure:
- persisted source text remains unchanged;
- selection ranges are computed over document text only;
- caret movement is computed over document text only;
- copy/paste operates on document text only;
- hint visibility does not alter the canonical file buffer.
### 6. Partial Degradation
When semantic analysis yields only partial valid hint data:
- valid hint spans MUST continue to render;
- invalid or missing spans MAY be omitted locally;
- the Studio MUST NOT disable all hints for the entire document solely because some hint spans could not be produced.
### 7. Initial Scope
This decision is initiated by the PBS need to show inferred type hints for local bindings such as `let`.
However, this decision does not lock hint eligibility to `let`.
Eligibility remains frontend-owned under the contract above.
### 8. Propagation Targets
This decision MUST be propagated to:
- Studio editor specifications covering editor rendering and semantic read surfaces;
- LSP specifications or contracts covering semantic transport payloads;
- implementation plans for frontend hint payload production, LSP transport, and Studio rendering;
- tests covering decorative behavior, anchor stability, partial degradation, and frontend-owned hint policy.
## Constraints
- No implementation plan may reinterpret Studio as semantic owner of hint content.
- No implementation plan may treat an approximate overlay as the final shipped architecture.
- No implementation plan may allow hints to become part of the editable document text model.
- If a later plan discovers that the current editor substrate cannot support inline real rendering cleanly, that plan MUST surface the substrate limitation explicitly and propose the required editor primitive or migration path rather than silently downgrading the final requirement.
## Revision Log
- 2026-04-03: Initial accepted decision from AGD-0018.

View File

@ -0,0 +1,32 @@
package p.studio.workspaces.editor.syntaxhighlight;
import java.util.List;
import java.util.regex.Pattern;
public final class EditorDocumentSyntaxHighlightingPbs {
public static final EditorDocumentSyntaxHighlighting PBS = new EditorDocumentSyntaxHighlighting(
Pattern.compile(
"(?<COMMENT>//[^\\n\\r]*)"
+ "|(?<STRING>\"(?:\\\\.|[^\"\\\\])*\")"
+ "|(?<NUMBER>\\b\\d+(?:\\.\\d+)?b?\\b)"
+ "|(?<LITERAL>\\b(?:true|false|none)\\b)"
+ "|(?<KEYWORD>\\b(?:import|from|as|service|host|fn|apply|bind|new|implements|using|ctor"
+ "|declare|let|const|global|struct|contract|error|enum|callback|builtin|self|this|pub|mut|mod|type"
+ "|if|else|switch|default|for|until|step|while|break|continue|return|void|optional|result"
+ "|some|ok|err|handle|and|or|not|spawn|yield|sleep|match)\\b)"
+ "|(?<FUNCTION>\\b[A-Za-z_][A-Za-z0-9_]*\\b(?=\\s*\\())"
+ "|(?<OPERATOR>\\+\\=|\\-\\=|\\*\\=|/\\=|%\\=|\\=\\=|!\\=|<\\=|>\\=|&&|\\|\\||\\->|[+\\-*/%!=<>?])"
+ "|(?<PUNCTUATION>\\.|\\.\\.|[(){}\\[\\],:;@])"),
List.of(
new EditorDocumentHighlightToken("COMMENT", "editor-semantic-pbs-comment"),
new EditorDocumentHighlightToken("STRING", "editor-semantic-pbs-string"),
new EditorDocumentHighlightToken("NUMBER", "editor-semantic-pbs-number"),
new EditorDocumentHighlightToken("LITERAL", "editor-semantic-pbs-literal"),
new EditorDocumentHighlightToken("KEYWORD", "editor-semantic-pbs-keyword"),
new EditorDocumentHighlightToken("FUNCTION", "editor-semantic-pbs-function"),
new EditorDocumentHighlightToken("OPERATOR", "editor-semantic-pbs-operator"),
new EditorDocumentHighlightToken("PUNCTUATION", "editor-semantic-pbs-punctuation")));
private EditorDocumentSyntaxHighlightingPbs() {
}
}