# 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`
- Attach to Module/Function/Variable via annotations link
- **Test:** build SimpleFunctionExample with `@Reclaim(Tracing)` (initially stored as `DerefStrategy("batched")`), verify annotation reads back

### 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)
- 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

> **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++ | 1–7 | 33 concepts as C++ objects, JSON round-trip, schema validation |
| 2b: First Generator | 8–11 | Python output matching MPS for all examples |
| 2c: Dear ImGui Shell | 12–15 | Window showing live AST projection with toggle |
| 2d: Orchestrator | 16–21 | Separate process, RPC mutations, undo/redo, ImGui connected |
| 2e: Structured Editing | 22–25 | Build code through UI, scope-aware dropdowns |
| 2f: Emacs Integration | 26–29 | File ops, search, git via headless Emacs servers |
| 2g: Elisp Projection | 30–33 | Generate and parse Elisp, round-trip verified |
| 2h: C++ + Agent API | 34–38 | 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 |
