From 5f7e0e2bef63041c4d8198bffe457912e795f34e Mon Sep 17 00:00:00 2001 From: bQUARKz Date: Tue, 31 Mar 2026 00:44:25 +0100 Subject: [PATCH] editor workspace foundation --- .../.backups/index.ndjson.20260331-004213.bak | 12 ++ ...ditor-foundations-and-semantic-deferral.md | 146 ++++++++++++++++++ 2 files changed, 158 insertions(+) create mode 100644 discussion/.backups/index.ndjson.20260331-004213.bak create mode 100644 discussion/lessons/DSC-0010-studio-code-editor-workspace-foundations/LSN-0026-read-only-editor-foundations-and-semantic-deferral.md diff --git a/discussion/.backups/index.ndjson.20260331-004213.bak b/discussion/.backups/index.ndjson.20260331-004213.bak new file mode 100644 index 00000000..bf3215ca --- /dev/null +++ b/discussion/.backups/index.ndjson.20260331-004213.bak @@ -0,0 +1,12 @@ +{"type":"meta","next_id":{"DSC":12,"AGD":12,"DEC":9,"PLN":15,"LSN":26,"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-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-0004","status":"open","ticket":"tilemap-and-metatile-runtime-binary-layout","title":"Tilemap and Metatile Runtime Binary Layout","created_at":"2026-03-26","updated_at":"2026-03-26","tags":["packer","legacy-import","tilemap","metatile","runtime-layout"],"agendas":[{"id":"AGD-0004","file":"AGD-0004-tilemap-and-metatile-runtime-binary-layout.md","status":"open","created_at":"2026-03-26","updated_at":"2026-03-26"}],"decisions":[],"plans":[],"lessons":[]} +{"type":"discussion","id":"DSC-0005","status":"open","ticket":"variable-tile-bank-palette-serialization","title":"Variable Tile Bank Palette Serialization","created_at":"2026-03-26","updated_at":"2026-03-26","tags":["packer","legacy-import","tile-bank","palette-serialization","versioning"],"agendas":[{"id":"AGD-0005","file":"AGD-0005-variable-tile-bank-palette-serialization.md","status":"open","created_at":"2026-03-26","updated_at":"2026-03-26"}],"decisions":[],"plans":[],"lessons":[]} +{"type":"discussion","id":"DSC-0006","status":"done","ticket":"pbs-game-facing-asset-refs-and-call-result-discard","title":"PBS Game-Facing Asset References and Ignored Call Result Lowering","created_at":"2026-03-27","updated_at":"2026-03-30","tags":["compiler","pbs","ergonomics","lowering","runtime","asset-identity","expression-statements"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0024","file":"discussion/lessons/DSC-0006-pbs-game-facing-asset-refs-and-call-result-discard/LSN-0024-addressable-surface-host-metadata-and-ignored-value-discipline.md","status":"done","created_at":"2026-03-30","updated_at":"2026-03-30"}]} +{"type":"discussion","id":"DSC-0007","status":"done","ticket":"pbs-learn-to-discussion-lessons-migration","title":"Migrate PBS Learn Documents into Discussion Lessons","created_at":"2026-03-27","updated_at":"2026-03-27","tags":["compiler","pbs","migration","discussion-framework","lessons","learn-prune"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0018","file":"discussion/lessons/DSC-0007-pbs-learn-to-discussion-lessons-migration/LSN-0018-pbs-ast-and-parser-contract-legacy.md","status":"done","created_at":"2026-03-27","updated_at":"2026-03-27"},{"id":"LSN-0019","file":"discussion/lessons/DSC-0007-pbs-learn-to-discussion-lessons-migration/LSN-0019-pbs-name-resolution-and-linking-legacy.md","status":"done","created_at":"2026-03-27","updated_at":"2026-03-27"},{"id":"LSN-0020","file":"discussion/lessons/DSC-0007-pbs-learn-to-discussion-lessons-migration/LSN-0020-pbs-runtime-values-identity-memory-boundaries-legacy.md","status":"done","created_at":"2026-03-27","updated_at":"2026-03-27"},{"id":"LSN-0021","file":"discussion/lessons/DSC-0007-pbs-learn-to-discussion-lessons-migration/LSN-0021-pbs-diagnostics-and-conformance-governance-legacy.md","status":"done","created_at":"2026-03-27","updated_at":"2026-03-27"},{"id":"LSN-0022","file":"discussion/lessons/DSC-0007-pbs-learn-to-discussion-lessons-migration/LSN-0022-pbs-globals-lifecycle-and-published-entrypoint-legacy.md","status":"done","created_at":"2026-03-27","updated_at":"2026-03-27"}]} +{"type":"discussion","id":"DSC-0008","status":"done","ticket":"pbs-low-level-asset-manager-surface","title":"PBS Low-Level Asset Manager Surface for Runtime AssetManager","created_at":"2026-03-27","updated_at":"2026-03-27","tags":["compiler","pbs","runtime","asset-manager","host-abi","stdlib","asset"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0023","file":"discussion/lessons/DSC-0008-pbs-low-level-asset-manager-surface/LSN-0023-lowassets-runtime-aligned-sdk-surface.md","status":"done","created_at":"2026-03-27","updated_at":"2026-03-27"}]} +{"type":"discussion","id":"DSC-0009","status":"open","ticket":"studio-debugger-workspace-integration","title":"Integrate ../debugger into Studio as a dedicated workspace","created_at":"2026-03-30","updated_at":"2026-03-30","tags":["studio","debugger","workspace","integration","shell"],"agendas":[{"id":"AGD-0009","file":"AGD-0009-studio-debugger-workspace-integration.md","status":"open","created_at":"2026-03-30","updated_at":"2026-03-30"}],"decisions":[],"plans":[],"lessons":[]} +{"type":"discussion","id":"DSC-0010","status":"in_progress","ticket":"studio-code-editor-workspace-foundations","title":"Establish Code Editor workspace foundations in Studio without LSP","created_at":"2026-03-30","updated_at":"2026-03-30","tags":["studio","editor","workspace","multi-frontend","lsp-deferred"],"agendas":[{"id":"AGD-0010","file":"AGD-0010-studio-code-editor-workspace-foundations.md","status":"accepted","created_at":"2026-03-30","updated_at":"2026-03-30"}],"decisions":[{"id":"DEC-0008","file":"DEC-0008-studio-code-editor-read-only-workspace-foundations.md","status":"accepted","created_at":"2026-03-30","updated_at":"2026-03-30","ref_agenda":"AGD-0010"}],"plans":[{"id":"PLN-0012","file":"PLN-0012-studio-code-editor-spec-propagation.md","status":"done","created_at":"2026-03-30","updated_at":"2026-03-30","ref_decisions":["DEC-0008"]},{"id":"PLN-0013","file":"PLN-0013-editor-workspace-layout-and-passive-surfaces.md","status":"done","created_at":"2026-03-30","updated_at":"2026-03-30","ref_decisions":["DEC-0008"]},{"id":"PLN-0014","file":"PLN-0014-project-navigator-snapshot-and-read-only-file-opening.md","status":"done","created_at":"2026-03-30","updated_at":"2026-03-30","ref_decisions":["DEC-0008"]}],"lessons":[]} +{"type":"discussion","id":"DSC-0011","status":"done","ticket":"compiler-analyze-compile-build-pipeline-split","title":"Split compiler pipeline into analyze, compile, and build entrypoints","created_at":"2026-03-30","updated_at":"2026-03-30","tags":["compiler","pipeline","artifacts","build","analysis"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0025","file":"discussion/lessons/DSC-0011-compiler-analyze-compile-build-pipeline-split/LSN-0025-compiler-pipeline-entrypoints-and-result-boundaries.md","status":"done","created_at":"2026-03-30","updated_at":"2026-03-30"}]} diff --git a/discussion/lessons/DSC-0010-studio-code-editor-workspace-foundations/LSN-0026-read-only-editor-foundations-and-semantic-deferral.md b/discussion/lessons/DSC-0010-studio-code-editor-workspace-foundations/LSN-0026-read-only-editor-foundations-and-semantic-deferral.md new file mode 100644 index 00000000..6fb7d673 --- /dev/null +++ b/discussion/lessons/DSC-0010-studio-code-editor-workspace-foundations/LSN-0026-read-only-editor-foundations-and-semantic-deferral.md @@ -0,0 +1,146 @@ +--- +id: LSN-0026 +ticket: studio-code-editor-workspace-foundations +title: Read-Only Editor Foundations and Semantic Deferral +created: 2026-03-31 +tags: [studio, editor, workspace, read-only, navigator, tabs, lsp-deferred, ui-foundations] +--- + +## Context + +Studio needed a real `Code Editor` workspace, but the team explicitly did not want the first wave to collapse UI structure, file management, write behavior, and language semantics into one premature implementation. + +The discussion closed a narrower and more durable target: + +- Studio owns the editorial workspace shell. +- The first wave is read-only. +- The workspace must still be useful enough to navigate a full project and open files. +- Semantic behavior such as diagnostics, symbols, completion, or other LSP-like surfaces must remain deferred. + +This turned the problem from "build an editor" into "stabilize the workspace composition and file-management shell without hardcoding semantic ownership too early." + +## Key Decisions + +### Treat the First Editor Wave as an Editorial Shell, Not a Language Tool + +**What:** +The first `Code Editor` wave is a Studio-owned read-only workspace foundation with: + +- `Project Navigator` +- reserved `Outline` region +- responsive tab strip +- central read-only editor surface +- passive helper region +- passive status bar + +**Why:** +The workspace needed to become structurally real before it could safely host future semantic providers. +By freezing the editorial shell first, the team avoided inventing incomplete semantic behavior just to justify the layout. + +**Trade-offs:** +The result is intentionally incomplete as an editor. +It opens files and manages workspace composition, but it does not yet save, mark dirty state, or provide language-aware interactions. + +### Separate Structural Project State from Open-Document Content State + +**What:** +The final implementation keeps two different kinds of in-memory state: + +- a structural project-tree snapshot for navigation and visual state +- read-only file buffers only for opened files + +**Why:** +These are different responsibilities. +The navigator needs fast structural state over the whole project, while the editor only needs content snapshots for documents the user has actually opened. + +**Trade-offs:** +This adds a small amount of model code up front, but it keeps the workspace testable and prevents the navigator from degenerating into ad hoc filesystem reads during rendering. + +### Keep Semantic Ownership Deferred but Architectural Seams Open + +**What:** +The workspace now reserves real regions for future semantic surfaces such as `Outline`, helper features, and later LSP-backed integrations, but those surfaces remain passive in this wave. + +**Why:** +The important rule was not to "solve LSP later" by ignoring layout now. +The rule was to reserve the correct shell surfaces now without pretending semantic capability already exists. + +**Trade-offs:** +The first implementation includes visible placeholders and passive chrome. +That can feel sparse, but it prevents later layout churn and keeps ownership boundaries explicit. + +## Final Implementation + +The Studio domain now has a dedicated `Code Editor` workspace specification and a concrete read-only implementation: + +- `docs/specs/studio/5. Code Editor Workspace Specification.md` defines the normative first-wave contract. +- `EditorWorkspace` now mounts a left navigator column, reserved `Outline`, responsive tabs, read-only code area, helper region, and status bar. +- `EditorProjectSnapshotService` builds a full-project structural tree, including hidden files, folder-first ordering, alphabetical sorting, and frontend-root tagging from `prometeu.json`. +- `EditorOpenFileSession` keeps opened tabs session-local and read-only. +- unsupported or non-text files trigger an explicit modal instead of a fake preview. +- the navigator and status bar share a consistent visual language for folders, source roots, build directories, and `prometeu.json`. + +## Patterns and Algorithms + +### Pattern: Stabilize Workspace Chrome Before Semantic Capability + +When a new workspace will eventually host rich language tooling, first define and implement: + +1. shell composition +2. project navigation +3. document opening model +4. session-local view state +5. passive reserved regions for future semantic consumers + +Only after those are stable should the team decide how semantic providers plug into the shell. + +### Pattern: Make Read-Only a Deliberate First-Wave Contract + +Read-only mode is not just a shortcut. +It is a way to avoid accidentally committing to: + +- save semantics +- dirty tracking semantics +- conflict resolution UX +- write affordances +- or editor-to-filesystem mutation rules + +until those deserve their own discussion. + +### Pattern: Use Full-Project Visibility with Frontend-Aware Tagging + +The navigator should not hide non-source files just because the selected frontend only cares about some roots. +A better pattern is: + +- show the whole project +- tag the frontend-relevant roots +- and keep the filesystem as the source of truth + +This preserves workspace usability without confusing project ownership with compiler ownership. + +## Pitfalls + +- Do not let passive first-wave regions start pretending they are semantic features. +- Do not reintroduce save or dirty indicators without an explicit decision revision. +- Do not make the navigator a filtered "source-only" view when the workspace is supposed to expose the real project. +- Do not collapse structural snapshot state and open-document content buffers into one model. +- Do not let visual polish quietly smuggle new product behavior into a read-only wave. + +## References + +- `DEC-0008` Read-only foundations for the Studio Code Editor workspace +- `PLN-0012` Propagate DEC-0008 into Studio shell and workspace specs +- `PLN-0013` Implement the read-only Code Editor workspace shell and passive surfaces +- `PLN-0014` Implement the Project Navigator snapshot and read-only file opening flow +- `docs/specs/studio/5. Code Editor Workspace Specification.md` +- `docs/specs/studio/1. Studio Shell and Workspace Layout Specification.md` +- `docs/specs/studio/2. Studio UI Foundations Specification.md` +- `prometeu-studio/src/main/java/p/studio/workspaces/editor/EditorWorkspace.java` +- `prometeu-studio/src/main/java/p/studio/workspaces/editor/EditorProjectSnapshotService.java` +- `prometeu-studio/src/main/java/p/studio/workspaces/editor/EditorOpenFileSession.java` + +## Takeaways + +- A good first editor wave can be structurally complete while still being intentionally read-only. +- Structural project navigation and opened-document content are different state models and should stay separate. +- Future semantic integration becomes easier when the shell reserves the right surfaces early but refuses to fake capability before the contract exists.