prometeu-studio/discussion/lessons/DSC-0016-studio-editor-scope-guides-and-brace-anchoring/LSN-0034-active-scope-gutter-and-frontend-owned-structural-anchors.md
2026-04-06 04:39:27 +01:00

130 lines
6.5 KiB
Markdown

---
id: LSN-0034
ticket: studio-editor-scope-guides-and-brace-anchoring
title: Active-Scope Gutter and Frontend-Owned Structural Anchors
created: 2026-04-06
tags: [studio, editor, scope-guides, structural-anchors, semantic-read, frontend-contract]
---
## Context
The Studio editor already exposed structural guides in the gutter, but the old behavior mixed two different concerns:
- active-scope context in the editor UI,
- and exact structural start/end anchoring.
That combination caused two failures at once:
- the default gutter became visually noisy because it rendered a stacked ancestry map,
- and the guide geometry still depended on approximate local heuristics rather than on language-owned structural metadata.
This discussion split those concerns into a simpler first-wave editor behavior plus a stable long-term semantic contract.
## Key Decisions
### Limit the Default Gutter to `activeScope` and `activeContainer`
**What:**
The default editor gutter now renders at most two active structural indicators:
- `activeScope`, defined as the smallest structural range containing the caret;
- `activeContainer`, defined as the immediate structural ancestor of `activeScope`.
**Why:**
The stacked ancestry gutter produced too much visual noise for routine editing.
The editor needs the nearest structure context, not the whole ancestry map.
**Trade-offs:**
The first wave intentionally drops persistent visibility of higher ancestors.
That loses some ambient hierarchy, but it produces a much clearer default editing signal.
### Keep Exact Anchoring Frontend-Owned Through a Dedicated Semantic Surface
**What:**
Exact guide start and end positions now belong to a dedicated structural-anchor semantic surface rather than to `documentSymbols` or Studio-local text scanning.
**Why:**
Outline/navigation structure and guide geometry are different contracts.
Exact anchoring must survive languages with braces, keywords, indentation, or mixed delimiter schemes, so the final source of truth has to be frontend-owned and language-agnostic.
**Trade-offs:**
The transport and DTO surface become richer, and Studio must consume one more semantic payload.
That cost is worth it because it prevents brace-specific heuristics from becoming the canonical editor contract.
### Keep Presentation Ownership Out of the Core Contract
**What:**
The contract distinguishes semantic roles such as `activeContainer` and `activeScope`, but concrete styling remains frontend-owned.
**Why:**
The host should know which guide is which, but it should not freeze colors, strokes, or theme details into the semantic decision.
**Trade-offs:**
Presentation choices remain distributed across frontend or theme layers.
That is preferable to coupling semantic meaning to one hardcoded Studio style.
## Final Implementation
The final implementation landed across editor behavior, semantic transport, and specs:
- `EditorDocumentScopeGuideModel` now resolves `activeScope` as the smallest containing range and `activeContainer` as the immediate parent, with structural-anchor-aware construction when that metadata is available.
- `EditorWorkspace` recomputes active guide state from caret movement and prefers transported structural anchors over approximate local ranges when the analyze result includes them.
- `EditorDocumentScopeGuideGraphicFactory` renders the constrained two-slot gutter model instead of the old stacked active ancestry presentation.
- `LspStructuralAnchorDTO` and `prometeu-lsp` now expose a dedicated structural-anchor transport surface separate from `documentSymbols`.
- `SemanticIndex` derives exact structural anchors for Studio consumption.
- Studio and semantic-read specs now define the two-indicator gutter model, the dedicated structural-anchor surface, and the frontend-owned exact-anchor contract.
- Tests now cover smallest-containing-range selection, immediate-parent selection, structural-anchor transport, and anchor-aware rendering.
## Patterns and Algorithms
### Pattern: Split Local Active State from Exact Structural Geometry
The useful decomposition is:
- derive active editor context locally from the current structural range set;
- derive exact guide geometry from frontend-owned structural anchors.
The editor can therefore ship a useful first wave without inventing the long-term anchor contract.
### Pattern: Use the Smallest Containing Range as the Active Scope
When multiple structural ranges contain the caret, the active scope must be the nearest one, not the largest semantic owner.
That keeps the editor aligned with the user's current editing neighborhood.
### Example: Anchor Upgrade Path
The resulting flow is:
1. semantic read returns structural ranges and, when available, exact structural anchors;
2. Studio computes `activeScope` and `activeContainer` from containment;
3. gutter rendering uses exact anchor positions when present;
4. no fallback contract is allowed to redefine exact anchoring through source scanning.
## Pitfalls
- Do not overload `documentSymbols` with guide-only anchor data.
- Do not restore the full stacked ancestry gutter as the default active-scope experience.
- Do not treat brace scanning as a production contract for exact anchors.
- Do not promote high-level owners such as function or type when a nearer structural ancestor exists.
- Do not hardcode theme or stroke policy into the semantic guide model.
## References
- `DEC-0014` Code Editor active container, active scope, and frontend-owned structural anchors
- `PLN-0030` Wave 1 editor implementation for active container and active scope gutter indicators
- `PLN-0031` Structural anchor semantic surface specification for Studio semantic read
- `PLN-0032` Frontend structural-anchor payload propagation and anchor-aware test coverage
- `docs/specs/studio/5. Code Editor Workspace Specification.md`
- `docs/specs/studio/7. Integrated LSP Semantic Read Phase Specification.md`
- `prometeu-lsp/prometeu-lsp-api/src/main/java/p/studio/lsp/dtos/LspStructuralAnchorDTO.java`
- `prometeu-lsp/prometeu-lsp-v1/src/main/java/p/studio/lsp/models/SemanticIndex.java`
- `prometeu-studio/src/main/java/p/studio/workspaces/editor/EditorDocumentScopeGuideModel.java`
- `prometeu-studio/src/main/java/p/studio/workspaces/editor/EditorDocumentScopeGuideGraphicFactory.java`
- `prometeu-studio/src/main/java/p/studio/workspaces/editor/EditorWorkspace.java`
## Takeaways
- Active structure and exact anchor geometry should be modeled as separate concerns.
- The default gutter becomes much clearer when it shows only the nearest scope context.
- Exact structural anchors belong to a frontend-owned semantic surface, not to Studio heuristics.