--- id: PLN-0030 ticket: studio-editor-scope-guides-and-brace-anchoring title: Wave 1 editor implementation for active container and active scope gutter indicators status: review created: 2026-04-03 completed: tags: - studio - editor - scope-guides - gutter - active-scope --- ## Objective Implement the first Studio editor wave mandated by DEC-0014: a gutter-based active-structure indicator that renders at most two simultaneous states, `activeContainer` and `activeScope`, computed locally from existing structural ranges. ## Background The current editor renders a stacked multi-guide gutter model derived from document symbols. DEC-0014 replaces that default with a constrained active-state presentation: - keep scope indicators in the gutter; - compute `activeScope` as the smallest structural range containing the caret; - compute `activeContainer` as the immediate ancestor of `activeScope`; - render at most two indicators; - keep concrete styling frontend-owned. This plan intentionally covers only the editor-local behavior that can ship without structural-anchor metadata. ## Scope ### Included - Replace the default stacked guide presentation with an active-state model in `prometeu-studio`. - Extend the editor scope guide model so it can resolve `activeScope` and `activeContainer` from the caret offset. - Update gutter rendering to draw no more than two structural indicators. - Expose semantic slots or equivalent rendering states that allow presentation to distinguish container versus scope. - Add tests for active-scope selection and active-container selection. ### Excluded - Exact anchor positioning from structural metadata. - Changes to frontend payload schemas. - Changes to semantic read transport contracts outside what the editor already consumes. ## Execution Steps ### Step 1 - Refactor the local scope-guide model around structural containment **What:** Introduce a model capable of resolving structural containment from caret position and expressing the two active semantic states. **How:** Update `EditorDocumentScopeGuideModel` so it retains enough structural information to: - map paragraph and caret offsets back to containing structural ranges; - select the smallest containing range as `activeScope`; - select the immediate parent as `activeContainer`; - expose a paragraph-level view suitable for rendering only the relevant two indicators. Avoid any logic that promotes higher semantic owners such as function or type when a nearer ancestor exists. **File(s):** - `prometeu-studio/src/main/java/p/studio/workspaces/editor/EditorDocumentScopeGuideModel.java` - supporting editor model classes if extraction improves clarity ### Step 2 - Bind caret movement to active-state recomputation **What:** Recompute active structural state as the caret moves. **How:** Update `EditorWorkspace` to observe caret position changes from the `CodeArea`, resolve the current active structural state through the model, and refresh paragraph graphics when the active state changes. The implementation must remain language-agnostic and rely only on structural ranges already available through the semantic read result. **File(s):** - `prometeu-studio/src/main/java/p/studio/workspaces/editor/EditorWorkspace.java` ### Step 3 - Replace stacked guide rendering with a two-slot gutter renderer **What:** Redesign the gutter renderer so the default active-state UX shows at most `activeContainer` and `activeScope`. **How:** Update `EditorDocumentScopeGuideGraphicFactory` to consume the active-state data and render: - no indicator when no structural range contains the caret; - one indicator when only `activeScope` exists; - two distinguishable indicators when both `activeContainer` and `activeScope` exist. Do not hardcode semantic color contracts into decision logic. The renderer may expose separate style classes, paint roles, or equivalent slots so that presentation styling remains decoupled from the semantic model. **File(s):** - `prometeu-studio/src/main/java/p/studio/workspaces/editor/EditorDocumentScopeGuideGraphicFactory.java` - related editor presentation stylesheet hooks if necessary ### Step 4 - Update editor tests for the new active-state behavior **What:** Replace tests that validate the old stacked guide model as the default expectation. **How:** Add or update tests that cover: - smallest-containing-range selection for `activeScope`; - immediate-parent selection for `activeContainer`; - omission of `activeContainer` when no parent exists; - rendering behavior constrained to at most two semantic indicators. **File(s):** - `prometeu-studio/src/test/java/p/studio/workspaces/editor/EditorDocumentScopeGuideModelTest.java` - renderer tests or workspace tests if such coverage exists or needs to be introduced ## Test Requirements ### Unit Tests - Model tests for nested ranges and caret placement transitions. - Tests that prove immediate-parent selection rather than semantic-owner promotion. - Tests that prove no more than two semantic gutter indicators are active at once. ### Integration Tests - Editor workspace tests that move the caret through nested structures and validate gutter state transitions if an existing JavaFX/editor harness is available. ### Manual Verification - Open a frontend-backed document with nested scopes. - Move the caret across siblings, parent blocks, and root-level declarations. - Confirm that the gutter shows only `activeScope` and optional `activeContainer`. - Confirm that no full ancestry stack is shown by default. ## Acceptance Criteria - [ ] The default editor gutter no longer renders the old full stacked active-scope presentation. - [ ] `activeScope` is selected as the smallest structural range containing the caret. - [ ] `activeContainer` is selected as the immediate structural ancestor of `activeScope`. - [ ] The editor renders at most two active semantic indicators in the gutter. - [ ] The implementation remains language-agnostic and uses only existing structural ranges. ## Dependencies - Accepted decision `DEC-0014-studio-editor-active-scope-and-structural-anchors.md` - Existing semantic range payloads already consumed by `EditorWorkspace` ## Risks - Paragraph-graphic refreshes may become visually noisy or too expensive if caret updates are not throttled or diffed. - Existing tests may encode the previous stacked-gutter behavior and need coordinated updates. - The current model may need deeper refactoring than expected if it stores only per-line segments and not enough structural identity information.