Files
whetstone_DSL/docs/SPRINT_2_PLAN.md

289 lines
13 KiB
Markdown
Raw Permalink Normal View History

2026-02-06 19:31:38 -07:00
# Sprint 2 Plan: Whetstone Editor Stack
38 steps. Build one thing, test it, move on. If something breaks, the problem is in that step.
For detailed architecture and design rationale, see:
- `SPRINT_2_VISION.md` — Architecture diagrams, structured editing UI, agent API design
- `annotations/C++ Implementation Roadmap.md` — Full technical specs for each component (§1§7)
---
## Phase 2a: AST in C++
Port the 33 SemAnno concepts from MPS XML into C++ data structures.
### Step 1: Base node + one concept
- `ASTNode` base class with ID, concept type tag, parent pointer
- `Module` concept only — properties (name, targetLanguage), empty child vectors
- **Test:** create a Module in C++, verify fields work
### Step 2: Child links
- Add child link support to `ASTNode` (single-valued and multi-valued)
- Add `Function` and `Variable` concepts as children of Module
- **Test:** build Module → Function tree in code, walk it, verify parent/child pointers
### Step 3: Remaining concepts
- Add all Statement, Expression, Literal, and Type concepts
- Each one gets its own properties and child link definitions
- **Test:** build the Calculator example as a C++ object graph
### Step 4: Annotation concepts
- Add memory strategy annotations (`DerefStrategy` as initial implementation), `OptimizationLock`, `LangSpecific`
2026-02-06 19:31:38 -07:00
- Attach to Module/Function/Variable via annotations link
- **Test:** build SimpleFunctionExample with `@Reclaim(Tracing)` (initially stored as `DerefStrategy("batched")`), verify annotation reads back
2026-02-06 19:31:38 -07:00
### Step 5: JSON serialization (save)
- Serialize the C++ AST graph to JSON
- One function: `toJson(ASTNode*) → nlohmann::json`
- **Test:** build Calculator graph → serialize → inspect JSON output by hand
### Step 6: JSON deserialization (load)
- Parse JSON back into C++ AST graph
- One function: `fromJson(nlohmann::json) → ASTNode*`
- **Test:** save Calculator → load it back → save again → compare JSON (byte-identical)
> **CHECKPOINT:** AST round-trips through JSON. Save → load → save produces identical output. Stop here until this passes.
### Step 7: Schema validation
- `ASTSchema` class: for each concept, list legal child types per role + cardinalities
- Validation function: `isLegalChild(parentConcept, role, childConcept) → bool`
- **Test:** legal placements accepted, illegal placements rejected (e.g., Module as child of IntegerLiteral)
---
## Phase 2b: First Generator
Python generator — port of the working MPS textGen rules into C++ visitor methods.
### Step 8: Generator base + Module/Function
- `ProjectionGenerator` base with visitor dispatch
- `PythonGenerator`: generate Module header and Function signatures only
- **Test:** Calculator AST → Python output has correct `def add(x, y):` signature
### Step 9: Statements and expressions
- Add Assignment, Return, BinaryOperation, VariableReference to Python generator
- **Test:** Calculator AST → full Python output matches MPS textGen output
> **CHECKPOINT:** Python generator matches MPS. Calculator output identical to what MPS produces. Stop here until this passes.
### Step 10: Remaining Python concepts
- Literals, control flow (If/While/For), types, FunctionCall, IndexAccess, MemberAccess
- **Test:** ConditionalExample AST → correct Python with if/else
### Step 11: Annotation output
- Memory annotations → `# @Reclaim(Tracing)` / `# @Deallocate(Explicit)` / etc. comment in Python (initially emits as `# @deref(strategy)` — Sprint 3 updates to canonical names)
2026-02-06 19:31:38 -07:00
- OptimizationLock → `# @lock(...)` comment
- **Test:** SimpleFunctionExample with annotations → comments appear in output
---
## Phase 2c: Dear ImGui Shell
Pure presentation layer — no business logic.
### Step 12: Window + empty layout
- Dear ImGui + SDL2 scaffold: opens a window with docking enabled
- Empty panes: file tree (left), editor area (center), panel (bottom)
- **Test:** app launches, window renders, panes are resizable
### Step 13: Text viewport
- Load a hardcoded Python string into the editor pane
- Render with monospace font, line numbers in gutter
- **Test:** text displays correctly, scrolls
### Step 14: AST → text viewport
- Connect: load Calculator JSON → build AST → run Python generator → display in viewport
- **Test:** change the JSON file, restart, see different output
> **CHECKPOINT:** ImGui shows live AST. Change JSON, restart, see different output. Stop here until this passes.
### Step 15: Projection toggle
- Toolbar with [Python] [AST] buttons
- Python: show generated code. AST: show JSON tree dump
- **Test:** toggle between views, both render correctly
---
## Phase 2d: Orchestrator (Standalone Process)
The brain — separate C++ process that owns the AST and coordinates everything.
### Step 16: Orchestrator process + AST ownership
- Separate C++ process that loads AST from JSON and holds it in memory
- Exposes nothing yet — just loads, holds, saves on exit
- **Test:** start orchestrator with Calculator.json, kill it, verify JSON saved back
### Step 17: JSON-RPC server
- Orchestrator listens on a Unix socket (or named pipe on Windows)
- Responds to `ping` and `getAST` methods
- **Test:** send JSON-RPC from a Python script, get response
### Step 18: AST mutation via RPC
- Add `setProperty` method: change a node's property value via RPC
- Validate against schema before applying
- **Test:** change Calculator function name via RPC, query AST back, see new name
### Step 19: Insert and delete via RPC
- `insertNode(parentId, role, conceptType, properties)` — creates node, validates, inserts
- `deleteNode(nodeId)` — removes node and subtree
- **Test:** insert a new Parameter via RPC, delete it, verify AST integrity
### Step 20: Undo/redo
- Operation journal: each mutation recorded as a reversible op
- `undo` and `redo` RPC methods
- **Test:** insert node → undo → node gone → redo → node back
### Step 21: Connect ImGui to orchestrator
- ImGui shell connects to orchestrator via JSON-RPC instead of loading JSON directly
- Requests AST on startup, displays projection
- **Test:** launch orchestrator, launch ImGui shell, see Calculator output
> **CHECKPOINT:** ImGui talks to orchestrator. Two processes running, viewport shows AST content. Stop here until this passes.
---
## Phase 2e: Structured Editing
Build code by choosing from valid options — no typing syntax.
### Step 22: Construct chooser (read-only)
- ImGui panel queries orchestrator: `getValidConstructs(parentId, role)` → list of legal types
- Display as button grid
- **Test:** click on Function body → see [Assignment] [Return] [If] [While] [For] etc.
### Step 23: Insert from chooser
- Click a construct button → orchestrator creates node with default properties
- Viewport refreshes with new projection
- **Test:** add a Return statement to a function, see it in Python output
### Step 24: Property editing
- Click a node → property panel shows editable fields (name, type, operator, etc.)
- Edit field → `setProperty` RPC → viewport refreshes
- **Test:** rename a function, see output update
### Step 25: Scope-aware dropdowns
- Orchestrator implements `getInScopeSymbols(nodeId)` → variables, functions, types visible at that position
- VariableReference name field shows dropdown of in-scope variables
- **Test:** inside Calculator.add body, dropdown shows [x, y, result]
> **CHECKPOINT:** Structured editing works. Build a function entirely through the UI. Stop here until this passes.
---
## Phase 2f: Emacs Integration
Headless Emacs servers for file ops, search, git, completion.
### Step 26: Spawn one headless Emacs
- Orchestrator spawns `emacs --daemon=whetstone-file --load whetstone-bridge.el`
- Sends a test command via `emacsclient`, gets response
- **Test:** orchestrator starts, Emacs server responds to ping
### Step 27: File operations
- `openFile(path)` → routes to Emacs file-server → returns contents
- `saveFile(path, contents)` → writes via Emacs
- **Test:** open a file through orchestrator, verify contents match
### Step 28: Search
- `search(query)` → routes to Emacs search-server → returns file:line results
- Results displayed in ImGui panel
- **Test:** search for "calculate_sum", get result pointing to SimpleFunctionExample
### Step 29: Server pool
- Multiple Emacs daemons: file-server, search-server, git-server
- Orchestrator routes by method name
- Health monitoring: restart crashed servers
- **Test:** kill a server, verify orchestrator restarts it and retries the request
> **CHECKPOINT:** Emacs servers respond. File open, search, and git status all return results. Stop here until this passes.
---
## Phase 2g: Elisp Projection
Generate Elisp from AST, and parse Elisp into AST.
### Step 30: Elisp generator — functions and variables
- Module → `(provide 'name)`, Function → `(defun name (params) body)`, Variable → `(defvar name value)`
- **Test:** Calculator AST → valid Elisp that loads in Emacs without errors
### Step 31: Elisp generator — statements and expressions
- Assignment → `(setq target value)`, Return → value (last expression), If → `(if cond then else)`
- BinaryOperation → `(op left right)`, Literals → values
- **Test:** ConditionalExample AST → Elisp with `(if (= status_code 200) "OK" "Error")`
### Step 32: Elisp parser (tree-sitter)
- Integrate tree-sitter-elisp, parse a `.el` file into CST
- Map `defun` → Function, `defvar` → Variable, `if` → IfStatement
- **Test:** parse a small hand-written `.el` file → inspect resulting AST
### Step 33: Elisp round-trip
- Parse `.el` → AST → generate Elisp → compare with original
- Handle `@LangSpecific` for idioms that don't map cleanly
- **Test:** write a 3-function `.el` file, round-trip it, verify semantic equivalence
> **CHECKPOINT:** Elisp round-trips. Parse .el → AST → generate .el → semantically equivalent. Stop here until this passes.
---
## Phase 2h: C++ Generator + Agent API
The final projection and the external agent interface.
### Step 34: C++ generator — basic output
- Module → `#include` guards, Function → typed signatures, variables → declarations
- No memory strategy yet — just syntactically valid C++
- **Test:** Calculator AST → compilable C++ with g++
### Step 35: C++ generator — memory strategies
- `@Deallocate(Explicit)` → raw pointers, `@Reclaim(Tracing)` → shared_ptr, `@Lifetime(RAII)` / `@Owner(Single)` → unique_ptr
- **Test:** same AST with different memory annotations → different C++ output, all compile
2026-02-06 19:31:38 -07:00
> **CHECKPOINT:** C++ compiles from AST. Generated C++ compiles with g++ for all 3 example models. Stop here until this passes.
### Step 36: Agent API
- Orchestrator accepts JSON-RPC from external clients (same protocol as ImGui)
- `getValidConstructs`, `insertNode`, `setProperty`, `getInScopeSymbols`
- **Test:** Python script acts as agent, builds a Function node by node via RPC
### Step 37: Agent batch mode
- `insertSubtree(parentId, role, jsonSubtree)` — submit entire subtree at once
- Orchestrator validates recursively, applies atomically (all or nothing)
- **Test:** agent submits full ConditionalExample as JSON, orchestrator builds the AST
> **CHECKPOINT:** Agent builds AST remotely. Python script creates full ConditionalExample via RPC. Stop here until this passes.
### Step 38: OptimizationLock warnings
- When mutating a locked node, orchestrator returns warning (not rejection)
- ImGui shows lock icon + banner
- Shadow system: original annotation preserved, modification tracked via `@provenance`
- **Test:** lock a function, modify it, verify warning fires and original preserved
---
## Summary
| Phase | Steps | What You Have When Done |
|-------|-------|------------------------|
| 2a: AST in C++ | 17 | 33 concepts as C++ objects, JSON round-trip, schema validation |
| 2b: First Generator | 811 | Python output matching MPS for all examples |
| 2c: Dear ImGui Shell | 1215 | Window showing live AST projection with toggle |
| 2d: Orchestrator | 1621 | Separate process, RPC mutations, undo/redo, ImGui connected |
| 2e: Structured Editing | 2225 | Build code through UI, scope-aware dropdowns |
| 2f: Emacs Integration | 2629 | File ops, search, git via headless Emacs servers |
| 2g: Elisp Projection | 3033 | Generate and parse Elisp, round-trip verified |
| 2h: C++ + Agent API | 3438 | C++ generator with memory strategies, agent RPC interface |
## Dependencies
| Dependency | Version | Purpose |
|------------|---------|---------|
| Dear ImGui | 1.90+ | GUI rendering |
| SDL2 or GLFW | latest | Window/input backend for ImGui |
| Emacs | 29+ | Headless servers |
| nlohmann/json | 3.11+ | JSON serialization, JSON-RPC |
| tree-sitter | 0.22+ | Elisp/Python/C++ parsing |
| tree-sitter-elisp | latest | Elisp grammar |
| C++ compiler | C++20 | Entire C++ stack |
| GoogleTest | latest | C++ unit tests |