odd-studio 2.5.0 → 2.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "odd-studio",
3
- "version": "2.5.0",
3
+ "version": "2.6.0",
4
4
  "description": "Outcome-Driven Development for Claude Code — a planning and build harness for domain experts building serious software with AI.",
5
5
  "keywords": [
6
6
  "claude-code",
@@ -0,0 +1,208 @@
1
+ ---
2
+ name: excalidraw
3
+ description: Wireframe and diagram generation for UI/design planning
4
+ version: 1.1.0
5
+ author: ODD Studio
6
+ source: https://github.com/excalidraw/excalidraw
7
+ tags:
8
+ - ui-design
9
+ - wireframing
10
+ - planning
11
+ - visualization
12
+ ---
13
+
14
+ # Excalidraw Wireframe Generator
15
+
16
+ Generate `.excalidraw` wireframe files that can be opened in excalidraw.com or the VS Code Excalidraw extension.
17
+
18
+ ## How This Skill Works
19
+
20
+ When invoked, you MUST generate a valid `.excalidraw` JSON file. This is not a documentation skill — it is a generation skill. You produce output.
21
+
22
+ ## Output Format
23
+
24
+ Every invocation produces a `.excalidraw` file saved to `docs/wireframes/` in the project directory. The file is valid Excalidraw JSON that can be:
25
+ - Dragged into https://excalidraw.com for interactive editing
26
+ - Opened in VS Code with the Excalidraw extension
27
+ - Exported as PNG or SVG from either tool
28
+
29
+ ## Excalidraw JSON Schema
30
+
31
+ An `.excalidraw` file is JSON with this structure:
32
+
33
+ ```json
34
+ {
35
+ "type": "excalidraw",
36
+ "version": 2,
37
+ "source": "odd-studio",
38
+ "elements": [ ... ],
39
+ "appState": {
40
+ "gridSize": null,
41
+ "viewBackgroundColor": "#0a0a0f",
42
+ "theme": "dark"
43
+ },
44
+ "files": {}
45
+ }
46
+ ```
47
+
48
+ ### Element Types
49
+
50
+ Every element in the `elements` array has these common fields:
51
+
52
+ ```json
53
+ {
54
+ "id": "unique-id",
55
+ "type": "rectangle|ellipse|diamond|text|line|arrow",
56
+ "x": 0,
57
+ "y": 0,
58
+ "width": 100,
59
+ "height": 50,
60
+ "angle": 0,
61
+ "strokeColor": "#495057",
62
+ "backgroundColor": "#1e1e2e",
63
+ "fillStyle": "solid",
64
+ "strokeWidth": 1,
65
+ "roughness": 0,
66
+ "opacity": 100,
67
+ "roundness": { "type": 3 },
68
+ "seed": 1001,
69
+ "version": 1,
70
+ "isDeleted": false,
71
+ "boundElements": null,
72
+ "link": null,
73
+ "locked": false
74
+ }
75
+ ```
76
+
77
+ **Rectangle** — Use for containers, cards, buttons, inputs, navigation bars, progress bars:
78
+ - Set `roundness: { "type": 3 }` for rounded corners (cards, buttons)
79
+ - Set `roundness: null` for sharp corners (sidebars, headers)
80
+ - For buttons: small height (28-36), accent `backgroundColor`, `"transparent"` `strokeColor`
81
+ - For cards: `backgroundColor: "#313244"`, `strokeColor: "#495057"`
82
+ - For progress bars: two overlapping rectangles (background + fill)
83
+
84
+ **Text** — Use for labels, headings, body text:
85
+ ```json
86
+ {
87
+ "type": "text",
88
+ "text": "Your label here",
89
+ "fontSize": 14,
90
+ "fontFamily": 1,
91
+ "textAlign": "left",
92
+ "verticalAlign": "top"
93
+ }
94
+ ```
95
+ - Headings: `fontSize: 20-28`, `strokeColor: "#cdd6f4"`
96
+ - Body text: `fontSize: 13-14`, `strokeColor: "#cdd6f4"`
97
+ - Muted/secondary: `fontSize: 12-13`, `strokeColor: "#6c7086"`
98
+ - Accent text: `strokeColor: "#a78bfa"` (or project accent colour)
99
+
100
+ **Ellipse** — Use for avatars, status indicators:
101
+ - Equal width/height for circles
102
+
103
+ **Diamond** — Use for badges, decorative icons:
104
+ - Good for achievement/badge indicators
105
+
106
+ **Line** — Use for separators, connectors:
107
+ ```json
108
+ {
109
+ "type": "line",
110
+ "points": [[0, 0], [200, 0]]
111
+ }
112
+ ```
113
+
114
+ **Arrow** — Use for flow indicators, data flow diagrams:
115
+ ```json
116
+ {
117
+ "type": "arrow",
118
+ "points": [[0, 0], [200, 0]],
119
+ "startArrowhead": null,
120
+ "endArrowhead": "arrow"
121
+ }
122
+ ```
123
+
124
+ ### Colour Palettes
125
+
126
+ **Dark mode (Catppuccin Mocha — default for ODD Studio):**
127
+ - Background: `#1e1e2e`
128
+ - Surface/cards: `#313244`
129
+ - Surface darker: `#181825`
130
+ - Border: `#495057`
131
+ - Muted surface: `#45475a`
132
+ - Text primary: `#cdd6f4`
133
+ - Text muted: `#6c7086`
134
+ - Accent purple: `#a78bfa`
135
+ - Success green: `#a6e3a1`
136
+ - Warning amber: `#fab387`
137
+ - Error red: `#f38ba8`
138
+ - Canvas background: `#0a0a0f`
139
+
140
+ **Light mode:**
141
+ - Background: `#ffffff`
142
+ - Surface/cards: `#f8f9fa`
143
+ - Border: `#dee2e6`
144
+ - Text primary: `#212529`
145
+ - Text muted: `#6c757d`
146
+ - Accent blue: `#3b82f6`
147
+ - Canvas background: `#f5f5f5`
148
+
149
+ ### Layout Patterns
150
+
151
+ **Desktop (1280x800):**
152
+ - Sidebar: x=0, width=240, full height
153
+ - Main content: x=280 (240 sidebar + 40 padding)
154
+ - Content width: ~960px
155
+ - Card grid: 3 columns at 300px each with 30px gaps
156
+
157
+ **Mobile (375x812):**
158
+ - Full-width cards with 16px padding each side (x=16, width=343)
159
+ - Header bar: height=60, full width
160
+ - Bottom tab bar: y=752, height=60, full width
161
+ - Stack cards vertically with 16px gaps
162
+
163
+ **Tablet (768x1024):**
164
+ - 2-column card grid
165
+ - Collapsible sidebar or top navigation
166
+
167
+ ### Wireframe Composition Rules
168
+
169
+ 1. **Always include a label** above each wireframe frame identifying it (e.g., "DESKTOP — Student Dashboard (1280x800)")
170
+ 2. **Use realistic content** — not "Lorem ipsum". Use domain-specific text from the specification.
171
+ 3. **Show the key outcome flow** — the most important screen the persona interacts with.
172
+ 4. **Include navigation** — sidebar on desktop, bottom tabs on mobile.
173
+ 5. **Show data states** — progress bars should show realistic percentages, cards should have real titles.
174
+ 6. **Use the project's accent colour** consistently for interactive elements (buttons, active tabs, links).
175
+ 7. **Keep `roughness: 0`** for clean wireframes. Use `roughness: 1` only if a hand-drawn sketch style is requested.
176
+
177
+ ### Generating Multiple Views
178
+
179
+ When generating wireframes for Step 9b (UI & Design Decision), create separate files for each design approach:
180
+
181
+ - `docs/wireframes/minimalist-dark.excalidraw` — dark mode, minimal, shadcn/ui
182
+ - `docs/wireframes/dense-dashboard-light.excalidraw` — light mode, data-dense, tables
183
+ - `docs/wireframes/minimal-accessible.excalidraw` — high contrast, large targets, WCAG AAA
184
+ - `docs/wireframes/brand-driven.excalidraw` — custom palette, domain-specific visual language
185
+
186
+ Each file should contain both desktop and mobile views side-by-side on the same canvas:
187
+ - Desktop frame at x=0
188
+ - Mobile frame at x=(desktop width + 120)
189
+
190
+ ### Seed Values
191
+
192
+ Every element needs a unique `seed` value (integer). Use a simple incrementing counter:
193
+ - Desktop elements: 1001, 1002, 1003...
194
+ - Mobile elements: 2001, 2002, 2003...
195
+ - Additional views: 3001, 3002, 3003...
196
+
197
+ ## Usage
198
+
199
+ When the `/excalidraw` command is invoked with arguments, parse the arguments to understand:
200
+ 1. What to wireframe (which screen, which persona, which outcome)
201
+ 2. Which design approach (dark/light, minimal/dense, accessible, brand-driven)
202
+ 3. Which devices (desktop, mobile, tablet)
203
+
204
+ Then generate the `.excalidraw` JSON file using the schema above and save it to `docs/wireframes/[design-approach-name].excalidraw`.
205
+
206
+ After generating, tell the user:
207
+ - The file path
208
+ - How to open it: "Drag this file into excalidraw.com to view and edit interactively, or open it with the VS Code Excalidraw extension."
@@ -2,15 +2,15 @@
2
2
  import fs from 'fs-extra';
3
3
  import path from 'path';
4
4
  import os from 'os';
5
- import { execSync } from 'child_process';
6
5
 
7
6
  /**
8
7
  * Installs the excalidraw skill into Claude Code.
9
8
  *
10
- * This creates a wrapper skill that calls the excalidraw system to generate wireframes.
11
- * The skill is installed to ~/.claude/skills/excalidraw/
9
+ * Copies the SKILL.md (with full generation logic) from the bundled
10
+ * excalidraw-skill directory to ~/.claude/skills/excalidraw/
12
11
  */
13
12
  export default async function installExcalidraw(packageRoot, options = {}) {
13
+ const source = path.join(packageRoot, 'scripts', 'excalidraw-skill');
14
14
  const destination = path.join(os.homedir(), '.claude', 'skills', 'excalidraw');
15
15
 
16
16
  // Ensure ~/.claude/skills/ exists
@@ -22,159 +22,8 @@ export default async function installExcalidraw(packageRoot, options = {}) {
22
22
  await fs.move(destination, backup);
23
23
  }
24
24
 
25
- // Create the excalidraw skill wrapper directory
26
- await fs.ensureDir(destination);
27
-
28
- // Create the SKILL.md manifest
29
- const skillManifest = `---
30
- name: excalidraw
31
- description: Wireframe and diagram generation for UI/design planning
32
- version: 1.0.0
33
- author: ODD Studio
34
- source: https://github.com/excalidraw/excalidraw
35
- tags:
36
- - ui-design
37
- - wireframing
38
- - planning
39
- - visualization
40
- ---
41
-
42
- # Excalidraw Wireframe Generator
43
-
44
- Generate interactive wireframes and diagrams for design planning, prototyping, and visual communication.
45
-
46
- ## Installation
47
-
48
- This skill is automatically installed by ODD Studio during project initialization.
49
-
50
- ## Usage
51
-
52
- Use the excalidraw skill to generate wireframes for design review:
53
-
54
- \`\`\`
55
- /excalidraw
56
-
57
- Generate wireframes for [Design Approach Name] for our [project name] platform.
58
-
59
- Context:
60
- - Primary persona: [name], a [role]
61
- - Key outcome: [outcome name] — [description]
62
- - Approach philosophy: [design approach philosophy]
63
- - Devices: [device types]
64
- - Visual style: [style description]
65
-
66
- Show:
67
- 1. Desktop layout
68
- 2. Mobile layout (if applicable)
69
- 3. Key UI components
70
- 4. Navigation pattern
71
- \`\`\`
72
-
73
- ## When to Use
74
-
75
- - **Step 9b of Build Planning**: Generate wireframes for different design approach options
76
- - **UI Design Review**: Create visual mockups for domain expert feedback
77
- - **System Architecture Documentation**: Diagram system flows and component relationships
78
- - **Accessibility Planning**: Sketch layouts with accessibility requirements in mind
79
-
80
- ## Features
81
-
82
- - Interactive canvas — edit and iterate on wireframes in real-time
83
- - Infinite canvas — zoom and pan without limits
84
- - Collaboration-ready — export diagrams for sharing with team members
85
- - Library support — use common UI patterns and components
86
- - Multiple export formats — PNG, SVG, JSON for further editing
87
-
88
- ## Integration with ODD Studio
89
-
90
- Excalidraw is deeply integrated into the ODD planning workflow:
91
-
92
- 1. **Step 9 (Technical Architecture)**: Plan database and framework choices
93
- 2. **Step 9b (UI & Design Decision)**: Generate 3-4 design approach wireframes using excalidraw
94
- 3. **Step 10 (Session Brief)**: Include wireframe references in the build specification
95
- 4. **Build Phase**: Build agents reference wireframes when implementing UI
96
-
97
- ## Notes
98
-
99
- - Wireframes generated in Step 9b are stored as \`.excalidraw\` files in \`docs/wireframes/\`
100
- - Each design approach option gets its own wireframe file
101
- - Domain expert selects preferred design from the wireframes
102
- - Selected design is recorded in \`CLAUDE.md\` under \`Design Approach\`
103
- `;
104
-
105
- await fs.writeFile(path.join(destination, 'SKILL.md'), skillManifest);
106
-
107
- // Create a README for setup instructions
108
- const readmeContent = `# Excalidraw Skill for ODD Studio
109
-
110
- This skill enables interactive wireframe and diagram generation within the ODD planning workflow.
111
-
112
- ## What Is Excalidraw?
113
-
114
- Excalidraw is a virtual whiteboard application for creating hand-drawn style diagrams, wireframes, and architectural sketches. It's simple, intuitive, and designed for collaborative design planning.
115
-
116
- ## Auto-Installed Components
117
-
118
- When you run \`npx odd-studio init\`, this skill is automatically installed with:
119
-
120
- - Claude Code integration configuration
121
- - ODD Studio-specific prompts and templates
122
- - Wireframing guidelines for design approach decisions
123
- - Export templates for Session Brief integration
124
-
125
- ## Using Excalidraw in ODD Studio
126
-
127
- ### Step 9b: Design Planning
128
-
129
- When Rachel (the Build Planner) reaches Step 9b (UI & Design Decision), you'll generate wireframes for each design approach option:
130
-
131
- \`\`\`
132
- /excalidraw
133
-
134
- Generate wireframes for [Design Approach] for [project name].
135
-
136
- Context:
137
- - Primary persona: [name]
138
- - Key outcome: [outcome]
139
- - Approach: [philosophy]
140
- - Devices: [device types]
141
-
142
- Show: Desktop layout, mobile (if applicable), key components, navigation
143
- \`\`\`
144
-
145
- ### Exporting Wireframes
146
-
147
- Export each set of wireframes as:
148
- - **Interactive .excalidraw file** — for iterating and refining
149
- - **PNG image** — for sharing with domain expert
150
- - **SVG vector** — for including in documentation
151
-
152
- Save wireframes to \`docs/wireframes/[design-approach-name]/\`
153
-
154
- ### In the Session Brief
155
-
156
- Reference wireframes in the Session Brief under the UI section:
157
-
158
- \`\`\`markdown
159
- ## Design Approach
160
-
161
- [Design approach name]
162
-
163
- See wireframes at: docs/wireframes/[design-approach-name]/
164
- \`\`\`
165
-
166
- ## Browser-Based
167
-
168
- Excalidraw works in any modern browser. If you have a local Excalidraw instance running, Claude Code will use it. Otherwise, the skill links to the official web version.
169
-
170
- ## Documentation
171
-
172
- - Official Excalidraw docs: https://excalidraw.com/
173
- - Excalidraw GitHub: https://github.com/excalidraw/excalidraw
174
- - ODD Studio integration guide: See \`SKILL.md\`
175
- `;
176
-
177
- await fs.writeFile(path.join(destination, 'README.md'), readmeContent);
25
+ // Copy the excalidraw skill directory (contains SKILL.md with generation logic)
26
+ await fs.copy(source, destination);
178
27
 
179
28
  return { destination };
180
29
  }
@@ -41,6 +41,18 @@ export default async function scaffoldProject(targetDir, projectName) {
41
41
  await fs.writeJson(stateFile, state, { spaces: 2 });
42
42
  }
43
43
 
44
+ // Create .vscode/extensions.json with recommended extensions
45
+ const vscodeDir = path.join(targetDir, '.vscode');
46
+ const extensionsFile = path.join(vscodeDir, 'extensions.json');
47
+ if (!fs.existsSync(extensionsFile)) {
48
+ await fs.ensureDir(vscodeDir);
49
+ await fs.writeJson(extensionsFile, {
50
+ recommendations: [
51
+ 'pomdtr.excalidraw-editor'
52
+ ]
53
+ }, { spaces: 2 });
54
+ }
55
+
44
56
  // Initialise git if not already a repo
45
57
  const gitDir = path.join(targetDir, '.git');
46
58
  if (!fs.existsSync(gitDir)) {
package/skill/SKILL.md CHANGED
@@ -250,17 +250,23 @@ Type `*build` to begin, or `*status` to see the full phase progress.
250
250
 
251
251
  Generate the IDE Session Brief. This is a standalone document that a developer or AI coding agent can use to execute a build session without needing to ask planning questions.
252
252
 
253
- Load `docs/plan.md` and all outcome files from `docs/outcomes/`. Generate `docs/session-brief.md` with:
253
+ Load `docs/plan.md` and all outcome files from `docs/outcomes/`. Check `.odd/state.json` for the current `sessionBriefCount` (default 0 if not set). Generate `docs/session-brief-[N].md` where N is the current count.
254
+
255
+ Include:
254
256
 
255
257
  - Project overview (one paragraph)
256
258
  - Active persona(s) for this session
257
259
  - Outcomes in scope (with full 6-field specification)
258
260
  - Contracts in play (what is produced, what is consumed)
261
+ - Available from previous phases (contracts already built)
259
262
  - Verification steps for each outcome
260
263
  - Build sequence (which outcome to start, which depends on which)
261
264
  - Any known constraints or failure paths to handle
265
+ - Changes from original plan (if any reconciliation has occurred)
266
+
267
+ Increment `sessionBriefCount` in `.odd/state.json`.
262
268
 
263
- After writing the file, display: "Your Session Brief has been written to docs/session-brief.md. Open it in your IDE or share it with your build AI to begin the session."
269
+ After writing the file, display: "Session Brief [N] has been written to docs/session-brief-[N].md. Open it in your IDE or share it with your build AI to begin the session."
264
270
 
265
271
  ---
266
272
 
@@ -587,7 +593,7 @@ At key moments in the methodology, proactively explain why the current step matt
587
593
  "Checkpoint runs automatically every time you confirm an outcome. It scans what was just built for security issues — exposed secrets, missing authentication checks, injection vulnerabilities — and briefs the build agent to fix anything it finds before you move on. You do not need to understand what it found or how it was fixed. Security is not a separate concern in ODD Studio. It is built into the rhythm of the build."
588
594
 
589
595
  **Phase complete:**
590
- "Phase complete. All outcomes in this phase have been verified and cleared by Checkpoint. The contracts they exposed are now available to the next phase. Well done — this is exactly how a well-planned build should progress."
596
+ "Phase complete. All outcomes in this phase have been verified and cleared by Checkpoint. The plan has been reconciled with changes from this phase, and Session Brief [N] has been generated for the next phase. Review it at `docs/session-brief-[N].md` or type `*build` to continue. All previous session briefs are retained. Well done — this is exactly how a well-planned build should progress."
591
597
 
592
598
  ---
593
599
 
@@ -83,7 +83,182 @@ Three checks run:
83
83
 
84
84
  **Cross-persona check.** Confirm each persona sees what they should see and cannot access what they should not. Navigate as a customer to a page that should only be accessible to an organiser. Confirm it is blocked.
85
85
 
86
- When all three checks pass, the phase is complete. ODD Studio marks it so, updates ruflo memory, and confirms which phase is next.
86
+ When all three checks pass, the phase is complete. ODD Studio runs the Phase Transition procedure.
87
+
88
+ ---
89
+
90
+ ## Phase Transition
91
+
92
+ When a phase is complete and all integration checks pass, ODD Studio advances to the next phase. This is a four-step process: mark complete, reconcile the plan, generate the next numbered brief, and confirm with the domain expert.
93
+
94
+ ---
95
+
96
+ ### Transition Step 1: Mark the current phase complete
97
+
98
+ Update `.odd/state.json`:
99
+ - Set the current phase status to `"complete"`
100
+ - Update `lastSessionDate`
101
+
102
+ Store completion in ruflo memory:
103
+
104
+ Call `mcp__ruflo__memory_store`:
105
+ - Key: `odd-phase-[phase-name]-complete`
106
+ - Namespace: `odd-project`
107
+ - Value: phase name, completion date, outcomes verified, integration checks passed
108
+
109
+ ---
110
+
111
+ ### Transition Step 2: Plan Reconciliation
112
+
113
+ During the build, things change. Specification gaps are discovered. The domain expert requests new features. A contract turns out to need a different shape. An outcome gets split into two. A service that was planned for a later phase gets pulled forward because the current phase needed it.
114
+
115
+ These changes happen *during* the build — they are recorded in ruflo memory as specification gaps, outcome updates, and contract changes. But `docs/plan.md` still reflects the original plan. If the next phase's brief is generated from a stale plan, it will conflict with reality.
116
+
117
+ **Before generating the next phase's brief, reconcile the plan.**
118
+
119
+ **2a. Gather all changes from the completed phase.**
120
+
121
+ Read from ruflo memory all changes recorded during the phase:
122
+
123
+ Call `mcp__ruflo__memory_search`:
124
+ - Query: `phase [completed-phase-name] changes`
125
+ - Namespace: `odd-project`
126
+
127
+ Also check:
128
+ - All outcome files in `docs/outcomes/` — compare current versions against the plan's original descriptions. Look for updated walkthroughs, new verification steps, changed contracts.
129
+ - The contract map in ruflo memory (`odd-contract-map`) — compare against `docs/contract-map.md`. Look for new contracts, changed data shapes, removed dependencies.
130
+ - Any `*outcome` edits made during the phase (specification gap fixes).
131
+ - Any new outcomes added during the build that were not in the original plan.
132
+
133
+ **2b. Classify each change.**
134
+
135
+ For each change found, classify it:
136
+
137
+ 1. **Contained change** — affects only the completed phase. No impact on future phases. Example: a verification step was reworded, a UI layout was adjusted, an error message was improved.
138
+
139
+ 2. **Contract change** — a contract's shape, name, or data flow was altered. This affects any future outcome that consumes this contract. Example: the mastery level contract now includes a `confidence_score` field that wasn't in the original plan.
140
+
141
+ 3. **New outcome** — a new outcome was identified during the build that needs to be added to a future phase. Example: during Phase 1, the domain expert realised students need a "review mistakes" feature that wasn't originally planned.
142
+
143
+ 4. **Moved outcome** — an outcome originally in a later phase was partially or fully built during this phase because it was needed earlier than planned. Example: basic parent notifications were built in Phase 1 because the teacher dashboard needed to reference them.
144
+
145
+ 5. **Removed or deferred outcome** — an outcome was removed from scope or moved to a later phase. Example: the gamification system was deprioritised to focus on core learning.
146
+
147
+ 6. **Dependency change** — a dependency between phases changed. Example: Phase 3 no longer depends on Phase 2's grouping feature because the parent dashboard was redesigned to use individual student data instead.
148
+
149
+ **2c. Update `docs/plan.md`.**
150
+
151
+ For each change that is NOT contained (types 2-6), update `docs/plan.md`:
152
+
153
+ - **Contract changes**: Update the contract descriptions in the plan. Note what changed and why.
154
+ - **New outcomes**: Add them to the appropriate phase. Re-run the dependency logic — does this new outcome depend on something that hasn't been built yet? If so, assign it to the correct phase.
155
+ - **Moved outcomes**: Update their phase assignment. Mark what was already built and what remains.
156
+ - **Removed/deferred outcomes**: Move them to a "Deferred" section at the bottom of the plan, with the reason.
157
+ - **Dependency changes**: Update the phase dependency descriptions.
158
+
159
+ Add a **Change Log** section at the bottom of `docs/plan.md`:
160
+
161
+ ```markdown
162
+ ## Change Log
163
+
164
+ ### After Phase [completed phase name] — [date]
165
+ - [Change type]: [description of what changed and why]
166
+ - [Change type]: [description]
167
+ - [Change type]: [description]
168
+ ```
169
+
170
+ **2d. Store the reconciled plan in ruflo memory.**
171
+
172
+ Call `mcp__ruflo__memory_store`:
173
+ - Key: `odd-plan`
174
+ - Namespace: `odd-project`
175
+ - Value: the full updated Master Implementation Plan
176
+
177
+ Call `mcp__ruflo__memory_store`:
178
+ - Key: `odd-plan-reconciliation-phase-[phase-name]`
179
+ - Namespace: `odd-project`
180
+ - Value: summary of all changes made during reconciliation, with classification and reasoning
181
+
182
+ **2e. Present the reconciliation to the domain expert.**
183
+
184
+ "Before I generate the next phase's brief, I need to account for what changed during the build. Here is what I found:
185
+
186
+ **Changes that affect future phases:**
187
+ - [list each non-contained change with its classification and impact]
188
+
189
+ **Changes contained to the completed phase (no impact on future phases):**
190
+ - [list contained changes — for information only]
191
+
192
+ **Updated plan:**
193
+ - [summary of how `docs/plan.md` was updated]
194
+ - [any outcomes added, moved, removed, or deferred]
195
+ - [any contract shapes that changed]
196
+
197
+ Does this reconciliation look correct? Are there any other changes from this phase that I missed?"
198
+
199
+ Wait for the domain expert to confirm before proceeding to Step 3.
200
+
201
+ ---
202
+
203
+ ### Transition Step 3: Generate the next numbered Session Brief
204
+
205
+ Session briefs are numbered sequentially. The first brief is `session-brief-0.md`. Each subsequent phase gets the next number.
206
+
207
+ Read `.odd/state.json` to get the current `sessionBriefCount`. The next brief is `docs/session-brief-[N].md` where N is the current count.
208
+
209
+ Generate the brief from the **reconciled** `docs/plan.md` (not the original plan). The brief must reflect any changes from Transition Step 2.
210
+
211
+ The brief follows the same structure as Step 10, with these additions:
212
+
213
+ - **"Available From Previous Phases"** section listing all contracts and infrastructure produced by completed phases
214
+ - **"Changes From Original Plan"** section listing any reconciliation changes that affect this phase — new outcomes added, contracts that changed shape, dependencies that shifted. If none: "No changes — this phase matches the original plan."
215
+
216
+ Save to `docs/session-brief-[N].md`.
217
+
218
+ Store in ruflo memory:
219
+
220
+ Call `mcp__ruflo__memory_store`:
221
+ - Key: `odd-session-brief-[N]`
222
+ - Namespace: `odd-project`
223
+ - Value: the contents of the new session brief
224
+
225
+ Update `.odd/state.json`:
226
+ - Set `currentBuildPhase` to the next phase
227
+ - Increment `sessionBriefCount`
228
+
229
+ ---
230
+
231
+ ### Transition Step 4: Confirm the transition
232
+
233
+ "Phase [completed phase name] is complete. All outcomes verified. All integration checks passed.
234
+
235
+ [If reconciliation found changes]: The plan has been updated to reflect [N] changes from this phase. Review the updated plan at `docs/plan.md`.
236
+
237
+ Session Brief [N] has been generated for Phase [next phase name]: [phase description]. This phase contains [n] outcomes: [list outcome names].
238
+
239
+ [If changes affect this phase]: Note: this phase has been updated since the original plan — [brief summary of what changed].
240
+
241
+ All previous session briefs are retained:
242
+ [list: session-brief-0.md through session-brief-[N-1].md]
243
+
244
+ Type `*build` to begin Phase [next phase name], or review the Session Brief at `docs/session-brief-[N].md` first."
245
+
246
+ ---
247
+
248
+ ### Transition Step 5: If this was the final phase
249
+
250
+ If no phases remain, the project build is complete. Update `.odd/state.json`:
251
+ - Set `currentPhase` to `"complete"`
252
+ - Set `buildComplete` to `true`
253
+
254
+ Confirm:
255
+
256
+ "All phases are complete. Every outcome has been verified and every integration check has passed. Your project is built.
257
+
258
+ Session briefs retained: [list all numbered briefs].
259
+ Plan reconciliation history: [list all reconciliation entries from the change log].
260
+
261
+ Review the full system end-to-end against your original personas. Does Alex experience what you documented? Does Sarah see what you specified? Does Jennifer receive what you described? If yes, your ODD project is done."
87
262
 
88
263
  ---
89
264
 
@@ -197,12 +197,14 @@ This is not a test. It is a check that the plan makes intuitive sense to the dom
197
197
 
198
198
  ---
199
199
 
200
- ## Step 9: Technical Architecture — Collaborative Decision-Making
200
+ ## Step 9: Technical Architecture — Component-by-Component Decision-Making
201
201
 
202
- The plan is structurally complete. Before the Session Brief is written and the build begins, the most consequential technical decision in the project must happen — and you and the domain expert will make it together.
202
+ The plan is structurally complete. Before the Session Brief is written and the build begins, the most consequential technical decisions in the project must happen — and you and the domain expert will make them together, one layer at a time.
203
203
 
204
204
  This step is fundamentally different from the previous eight. Until now, you drew out knowledge the domain expert already held. Now you bring technical expertise to the table. But expertise does not mean autonomous decision-making. It means presenting options with clear trade-offs, then stepping back while the domain expert chooses.
205
205
 
206
+ **Do NOT present a matrix of pre-bundled stacks.** Technology choices are independent — the domain expert should be able to choose Next.js with Supabase and NextAuth, or SvelteKit with Neon and Clerk, or any other valid combination. Each layer is its own decision.
207
+
206
208
  **Phase 1: Research and Prepare**
207
209
 
208
210
  Read the full specification to understand the constraints:
@@ -211,59 +213,63 @@ Read the full specification to understand the constraints:
211
213
  - Every contract: data relationships, how deeply interconnected the outcomes are
212
214
  - The phase structure: scale and depth of what is being built
213
215
 
214
- **Phase 2: Identify Realistic Options**
216
+ **Phase 2: Walk Through Each Decision — One at a Time**
215
217
 
216
- Based on this project's specification, identify 3-4 realistic technology stacks. Do NOT include absurd alternatives that no reasonable person would suggest. Include only credible options that would work for this kind of project.
218
+ Present each technology layer as its own decision. For each layer, present 3-4 credible options with trade-offs tied to THIS project's specification. Wait for the domain expert to choose before moving to the next layer.
217
219
 
218
- For each option, identify:
219
- - Core framework (Next.js, SvelteKit, Remix, Astro, etc.)
220
- - Database (PostgreSQL + Drizzle, MongoDB, Supabase, etc.)
221
- - Hosting (Vercel, AWS, self-hosted, etc.)
222
- - Authentication method (Clerk, Auth0, NextAuth, etc.)
223
- - Any specialized services (Stripe for payments, Resend for email, etc.)
220
+ **The sequence:**
224
221
 
225
- **Phase 3: Create a Comparison Matrix**
222
+ 1. Framework
223
+ 2. Database
224
+ 3. Authentication
225
+ 4. Hosting & Deployment
226
+ 5. Specialist Services (if needed — email, payments, real-time, etc.)
226
227
 
227
- Present the options side-by-side, with specific reasoning tied to THIS project:
228
+ For each layer, follow this pattern:
228
229
 
229
230
  ---
230
231
 
231
- **Technical Stack Options for [project name]:**
232
-
233
- | Component | Option A | Option B | Option C |
234
- |-----------|----------|----------|----------|
235
- | **Framework** | Next.js (App Router) | SvelteKit | Remix |
236
- | **Database + ORM** | PostgreSQL + Drizzle | MongoDB | Supabase (PostgreSQL) |
237
- | **Hosting** | Vercel | AWS Lambda | Self-hosted |
238
- | **Testing** | Vitest | Jest | Vitest |
239
- | **Best for** | [reason specific to spec] | [reason specific to spec] | [reason specific to spec] |
240
- | **Trade-off** | [specific cost] | [specific cost] | [specific cost] |
232
+ **Decision [N]: [Layer Name]**
241
233
 
242
- **Detailed reasoning for each option:**
234
+ "Now we choose your [layer]. Based on your specification, here are the realistic options:"
243
235
 
244
- **Option A — [name]**
245
- - Why it fits: [specific evidence from your specification: personas, walkthroughs, contracts]
246
- - What it handles well: [capabilities aligned to your outcomes]
247
- - Trade-off: [what you give up — complexity, cost, learning curve, etc.]
248
- - Example from your spec: [concrete reference to a outcome or persona that this solves for]
236
+ **[Option A]**
237
+ - What it is: [one sentence]
238
+ - Why it fits your project: [specific evidence from the specification — reference a persona, outcome, or contract]
239
+ - Trade-off: [what you give up — cost, complexity, lock-in, learning curve]
249
240
 
250
- **Option B — [name]**
251
- - Why it fits: [specific evidence from your specification]
252
- - What it handles well: [capabilities]
241
+ **[Option B]**
242
+ - What it is: [one sentence]
243
+ - Why it fits your project: [specific evidence from the specification]
253
244
  - Trade-off: [what you give up]
254
- - Example from your spec: [concrete reference]
255
245
 
256
- **Option C — [name]**
257
- - Why it fits: [specific evidence from your specification]
258
- - What it handles well: [capabilities]
246
+ **[Option C]**
247
+ - What it is: [one sentence]
248
+ - Why it fits your project: [specific evidence from the specification]
259
249
  - Trade-off: [what you give up]
260
- - Example from your spec: [concrete reference]
250
+
251
+ "Which of these fits best for your project? Are there constraints I don't know about that rule any of these out?"
261
252
 
262
253
  ---
263
254
 
264
- **Always include Drizzle and Vitest in every option.**
255
+ **Do not recommend. Offer. Let the domain expert choose.**
256
+
257
+ Wait for their answer. Record it. Move to the next layer.
265
258
 
266
- Regardless of the framework, database, or hosting choices, every stack includes:
259
+ If the domain expert raises a concern:
260
+ - If the concern reveals a constraint you missed: "You are right — I did not weight [constraint] heavily enough. Let me revise."
261
+ - If the concern is a misunderstanding: "I want to clarify — [option] actually handles [capability] this way."
262
+ - If the concern reveals a preference: "That preference carries a trade-off: [concrete consequence]. If you are comfortable with that, we proceed."
263
+
264
+ **Important rules for each decision:**
265
+ - Never bundle choices together. Framework is independent of database is independent of auth.
266
+ - Never exclude valid combinations. If someone wants Next.js + Supabase + NextAuth, that is a valid stack.
267
+ - Always tie reasoning to the specification. "This fits because Outcome 2.1 requires real-time updates for 90 students" — not "This is popular."
268
+ - If a previous choice constrains the next (e.g., choosing Supabase for database means Supabase Auth is available as an auth option), mention it as context but do not force it.
269
+
270
+ **Phase 3: Confirm the Fixed Layers**
271
+
272
+ After all choices are made, explain the two components that are included in every ODD Studio project regardless of choice:
267
273
 
268
274
  **Drizzle ORM** — the database layer that keeps the AI honest.
269
275
 
@@ -273,30 +279,29 @@ Regardless of the framework, database, or hosting choices, every stack includes:
273
279
 
274
280
  "Vitest runs the business rules and calculations you cannot verify by clicking — access control logic, pricing calculations, workflow state transitions. Every outcome built triggers Vitest automatically. If a rule breaks because of a change somewhere else, Vitest catches it before you reach the verification step."
275
281
 
276
- **Phase 4: The Domain Expert Decides**
282
+ These are not negotiable. They exist because the build agents need them, not because of preference.
277
283
 
278
- Present the matrix and ask directly:
284
+ **Phase 4: Summarise and Confirm**
279
285
 
280
- "I have identified three realistic technical stacks for your project. Each solves different constraints from your specification. Review them: the trade-offs are real, not cosmetic. Which approach best matches your priorities?
286
+ After all decisions are made, present the complete stack as a summary:
281
287
 
282
- Tell me:
283
- - Which option resonates with you, and why?
284
- - Are there constraints I do not know about — a team preference, a budget limit, a compliance requirement — that rules out any option?
285
- - Do you have experience with any of these that would make you more confident with one option?"
286
-
287
- **Do not recommend. Offer. Let the domain expert choose.**
288
+ "Here is the technical stack you have chosen, decision by decision:
288
289
 
289
- Listen to their choice. If they choose one of the options as presented, move to Phase 5. If they raise a concern about an option, address it:
290
+ - **Framework**: [chosen] because [reason from their decision]
291
+ - **Database**: [chosen] — because [reason from their decision]
292
+ - **ORM**: Drizzle (fixed — build agent requirement)
293
+ - **Auth**: [chosen] — because [reason from their decision]
294
+ - **Hosting**: [chosen] — because [reason from their decision]
295
+ - **Testing**: Vitest (fixed — build agent requirement)
296
+ - [Any specialist services]: [chosen] — because [reason from their decision]
290
297
 
291
- - If the concern reveals a constraint you missed: "You are right — I did not weight [constraint] heavily enough. Let me revise the options."
292
- - If the concern is a misunderstanding: "I want to clarify — [component] in [Option X] actually handles [capability] this way, because of [specific feature]."
293
- - If the concern reveals a preference: "I understand the preference for [alternative]. This choice carries a trade-off: [concrete consequence]. If you are comfortable with that, we proceed. If not, [other option] avoids it."
298
+ Does this look right? Any second thoughts before I record it?"
294
299
 
295
- The domain expert has the final say. They should make that decision with full information, not because they feel pressured.
300
+ Wait for confirmation. If they want to change a layer, go back to that specific decision do not re-run the entire sequence.
296
301
 
297
302
  **Phase 5: Record the Decision**
298
303
 
299
- When the domain expert has chosen, record their decision in CLAUDE.md and project memory.
304
+ When the domain expert confirms, record the complete stack in CLAUDE.md and project memory.
300
305
 
301
306
  Append a technical decisions section to `CLAUDE.md`:
302
307
 
@@ -307,22 +312,27 @@ Append a technical decisions section to `CLAUDE.md`:
307
312
  - Framework: [chosen]
308
313
  - Database: [chosen]
309
314
  - ORM: Drizzle
315
+ - Auth: [chosen]
310
316
  - Testing: Vitest
311
317
  - Hosting: [chosen]
312
318
  - [Other services]: [chosen]
313
319
 
314
- **Reasoning (tied to specification):**
315
- - [Component]: [why, with reference to specific outcome or persona]
316
- - [Component]: [why, with reference to specific outcome or persona]
320
+ **Decision reasoning (tied to specification):**
321
+ - Framework: [why, with reference to specific outcome or persona]
322
+ - Database: [why, with reference to specific outcome or persona]
323
+ - Auth: [why, with reference to specific outcome or persona]
324
+ - Hosting: [why, with reference to specific outcome or persona]
317
325
  - Drizzle: type-safe database layer with versioned migrations — build agents always know the exact shape of the data and every change is tracked alongside code changes
318
326
  - Vitest: automated testing for invisible business rules — catches regressions before verification
319
327
 
320
- **Alternatives considered:**
321
- - [Option X]: [why it did not fit — specific constraint from the specification]
322
- - [Option Y]: [why it did not fit — specific constraint from the specification]
328
+ **Alternatives considered (per layer):**
329
+ - Framework: [rejected options and why — specific constraint from the specification]
330
+ - Database: [rejected options and why]
331
+ - Auth: [rejected options and why]
332
+ - Hosting: [rejected options and why]
323
333
 
324
334
  **Domain expert decision notes:**
325
- [Any specific preferences, constraints, or reasoning the domain expert expressed]
335
+ [Any specific preferences, constraints, or reasoning the domain expert expressed across the decisions]
326
336
  ```
327
337
 
328
338
  **Store the decision in ruflo memory.**
@@ -330,16 +340,16 @@ Append a technical decisions section to `CLAUDE.md`:
330
340
  Call `mcp__ruflo__memory_store`:
331
341
  - Key: `odd-tech-stack`
332
342
  - Namespace: `odd-project`
333
- - Value: the complete technical stack decision with reasoning tied to the specification
343
+ - Value: the complete technical stack decision with per-layer reasoning tied to the specification
334
344
 
335
345
  **Update `.odd/state.json`:**
336
346
  - Set `techStackDecided: true`
337
- - Set `techStack` to the chosen stack description (e.g., "Next.js 16 + Neon PostgreSQL + Vercel + Clerk")
347
+ - Set `techStack` to the chosen stack description (e.g., "Next.js 16 + Supabase + NextAuth + Vercel")
338
348
  - Set `orm` to "Drizzle"
339
349
  - Set `testingFramework` to "Vitest"
340
350
  - Update `nextStep` to "Review UI and Design approach — type *build to continue"
341
351
 
342
- Confirm to the user: "Technical stack chosen and recorded. [Stack name] will be used for this project. Every build agent will read this before writing a line of code."
352
+ Confirm to the user: "Technical stack chosen and recorded. Every build agent will read this before writing a line of code."
343
353
 
344
354
  ---
345
355
 
@@ -484,15 +494,23 @@ Confirm to the user: "Design approach chosen and recorded. [Design approach name
484
494
 
485
495
  ## Step 10: Session Brief Export
486
496
 
487
- After the plan is approved, generate the Session Brief — the document a developer or build AI reads at the start of each build session.
497
+ After the plan is approved, generate the first Session Brief — the document a developer or build AI reads at the start of each build session.
488
498
 
489
- The Session Brief is saved to `docs/session-brief.md`.
499
+ **Session briefs are numbered.** Every phase gets its own brief, and all briefs are retained so the project has a complete history:
500
+
501
+ - `docs/session-brief-0.md` — Phase A (Foundation)
502
+ - `docs/session-brief-1.md` — Phase B (first outcomes)
503
+ - `docs/session-brief-2.md` — Phase C
504
+ - ...and so on.
505
+
506
+ The first brief generated here is always `docs/session-brief-0.md`.
490
507
 
491
508
  Structure:
492
509
 
493
510
  ```markdown
494
- # Session Brief — [Project Name] — Phase [X]: [Phase Name]
511
+ # Session Brief [N] — [Project Name] — Phase [X]: [Phase Name]
495
512
  Generated: [date]
513
+ Phase: [N] of [total]
496
514
 
497
515
  ## Overview
498
516
  [One paragraph describing the project, its domain, and its primary personas]
@@ -506,6 +524,9 @@ Generated: [date]
506
524
  ## Contracts In Play
507
525
  [Shared contracts needed for this phase, contracts produced by this phase, contracts consumed from previous phases]
508
526
 
527
+ ## Available From Previous Phases
528
+ [Contracts and infrastructure produced by completed phases — "None" for Phase A]
529
+
509
530
  ## Verification Steps
510
531
  [For each outcome: the complete verification checklist from the outcome specification]
511
532
 
@@ -517,9 +538,13 @@ Generated: [date]
517
538
 
518
539
  ## Not In Scope
519
540
  [Explicit list of things that are NOT to be built in this phase, to prevent scope creep]
541
+
542
+ ## Changes From Original Plan
543
+ [If this brief was generated after a plan reconciliation: list what changed and why.
544
+ "None — this is the original plan" for the first brief.]
520
545
  ```
521
546
 
522
- After writing the Session Brief, confirm: "Session Brief written to docs/session-brief.md. This is the primary input for your build agents. Share it with Claude or any other build AI to start the session."
547
+ After writing the Session Brief, confirm: "Session Brief 0 written to docs/session-brief-0.md. This is the primary input for your build agents."
523
548
 
524
549
  ---
525
550
 
@@ -537,14 +562,15 @@ Confirm to the user: "Master Implementation Plan saved to project memory. All bu
537
562
  Also store the Session Brief:
538
563
 
539
564
  Call `mcp__ruflo__memory_store`:
540
- - Key: `odd-session-brief-phase-[phase-name]`
565
+ - Key: `odd-session-brief-0`
541
566
  - Namespace: `odd-project`
542
- - Value: the contents of `docs/session-brief.md`
567
+ - Value: the contents of `docs/session-brief-0.md`
543
568
 
544
569
  Then update `.odd/state.json`:
545
570
  - Set `planApproved: true`
546
571
  - Populate `planPhases` with the array of phase names in build order
547
572
  - Set `currentBuildPhase` to Phase A
573
+ - Set `sessionBriefCount` to 1
548
574
  - Update `nextStep` to "Type *build — ODD Studio will scaffold the project, connect your services, and begin Phase A"
549
575
 
550
576
  ---