CallMeDaniel Claude Opus 4.6 (1M context) commited on
Commit
d7b4377
·
1 Parent(s): d94aafc

docs: add smart gap analysis & question cards design spec

Browse files

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

docs/superpowers/specs/2026-04-12-smart-gap-analysis-design.md ADDED
@@ -0,0 +1,333 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Smart Gap Analysis & Question Cards
2
+
3
+ **Date:** 2026-04-12
4
+ **Status:** Draft
5
+
6
+ ## Problem
7
+
8
+ When CAD, CNC, or CAM agents detect missing information, they respond with unstructured text ("NOT READY: need dimensions and material"). The orchestrator passes this message through to the user without analysis. The user must figure out what to provide and who to address. CNC and CAM agents lack any structured problem-reporting protocol at all.
9
+
10
+ ## Solution
11
+
12
+ 1. **Standardized NOT READY protocol** for CAD, CNC, and CAM agents.
13
+ 2. **Gap analyzer** that scans agent responses for NOT READY prefixes and categorizes missing items via regex/keyword matching.
14
+ 3. **Question cards** — actionable UI cards with the responsible agent, a question, and clickable suggestions — appended to the chat response.
15
+ 4. **Answers go through normal `sendMessage()` flow** — full crew routing, no special handling.
16
+
17
+ ## Agent Problem Reporting Protocol
18
+
19
+ All three output-producing agents (CAD, CNC, CAM) use the same prefix: `NOT READY:` followed by natural language listing what's missing.
20
+
21
+ ### Agent Task Description Changes
22
+
23
+ **CNC agent** — currently only says "ask a SPECIFIC clarifying question". New instruction appended to task description:
24
+
25
+ ```
26
+ If the design lacks critical manufacturability info (material, dimensions,
27
+ feature access, tolerance), start with 'NOT READY:' and list missing items.
28
+ If enough info exists, provide your manufacturability assessment.
29
+ ```
30
+
31
+ **CAM agent** — currently only says "create optimal machining strategy". New instruction appended to task description:
32
+
33
+ ```
34
+ If there is no CAD model generated yet or critical machining info is missing
35
+ (material, dimensions, surface finish requirements), start with 'NOT READY:'
36
+ and list missing items. If enough info exists, create the machining plan.
37
+ ```
38
+
39
+ **CAD agent** — unchanged. Already uses `NOT READY:` protocol.
40
+
41
+ **Design and Engineering agents** — unchanged. They stay conversational and exploratory.
42
+
43
+ ## Gap Analysis
44
+
45
+ ### Data Models
46
+
47
+ ```python
48
+ class MissingItem(BaseModel):
49
+ category: str # "dimension", "material", "feature", "constraint", etc.
50
+ description: str # "width", "wall thickness", "material selection"
51
+ agent_id: str # which agent flagged it
52
+
53
+ class GapAnalysis(BaseModel):
54
+ has_gaps: bool
55
+ missing_items: list[MissingItem]
56
+ ```
57
+
58
+ ### How It Works
59
+
60
+ 1. After all agent responses are collected, `analyze_gaps(responses)` scans each response.
61
+ 2. If an agent's message starts with `NOT READY:`, extract the text after the prefix.
62
+ 3. Run keyword/regex matching on that text to categorize missing items:
63
+
64
+ | Keywords in NOT READY text | Category | Responsible Agent |
65
+ |---|---|---|
66
+ | width, height, depth, length, diameter, dimension, size | `dimension` | engineering |
67
+ | material, alloy, grade, aluminum, steel, metal | `material` | engineering |
68
+ | shape, form, type, profile, geometry, what kind | `shape` | design |
69
+ | hole, fillet, chamfer, pocket, slot, feature | `feature` | design |
70
+ | tolerance, wall thickness, constraint, min wall, max size | `constraint` | engineering |
71
+ | axis, machine, setup, fixture, tool access | `machining` | cnc |
72
+ | surface finish, roughness, Ra | `finish` | cnc |
73
+ | model, CAD, 3D, generate | `model` | cad |
74
+
75
+ 4. Deduplicate — if both CAD and CNC flag "material", only one `MissingItem` is kept (first wins).
76
+ 5. Return `GapAnalysis` with the deduplicated list.
77
+
78
+ ### Agent Assignment
79
+
80
+ Each category maps to a "responsible agent" — the agent best suited to help the user provide that info. This mapping is configurable in `config.yaml` under `gap_analysis.category_agents`.
81
+
82
+ ## Question Cards
83
+
84
+ ### Data Model
85
+
86
+ ```python
87
+ class QuestionCard(BaseModel):
88
+ category: str # from MissingItem
89
+ question: str # human-readable question
90
+ responsible_agent: str # agent_id
91
+ agent_name: str # display name
92
+ agent_color: str # for frontend rendering
93
+ suggestions: list[str] # clickable options
94
+ allow_custom: bool # show free-text input
95
+ ```
96
+
97
+ ### Question Templates
98
+
99
+ | Category | Question | Suggestions |
100
+ |---|---|---|
101
+ | `dimension` | "What are the part dimensions?" | (none — free input fields for width/height/depth) |
102
+ | `material` | "What material should this be made from?" | ["Aluminum 6061", "Aluminum 7075", "Steel 304", "Steel 316", "Brass", "Titanium"] |
103
+ | `shape` | "What type of part are you designing?" | ["Bracket", "Enclosure", "Plate", "Shaft", "Gear", "Flange"] |
104
+ | `feature` | "What features does the part need?" | ["Mounting holes", "Fillets", "Chamfers", "Pockets", "Slots"] |
105
+ | `constraint` | "Are there any manufacturing constraints?" | ["Min wall 2mm", "Min wall 3mm", "Min wall 5mm"] |
106
+ | `machining` | "What machining approach?" | ["3-axis", "3+2-axis", "5-axis", "Auto"] |
107
+ | `finish` | "What surface finish is required?" | ["Standard", "Fine (Ra 1.6)", "Mirror (Ra 0.4)"] |
108
+ | `model` | "A 3D model is needed first. Provide more design details or approve the plan to generate." | (no suggestions — informational only) |
109
+
110
+ These templates are defined in code (not config) — they are tightly coupled to the category set.
111
+
112
+ ### Filtering Against Existing State
113
+
114
+ Before generating cards, `generate_question_cards(gap_analysis, design_state)` checks each `MissingItem` against the current `DesignState`:
115
+ - If `material` is already set, skip the material card even if an agent flagged it.
116
+ - If `dimensions` has entries, skip the dimension card.
117
+ - This prevents asking the user for info they already provided.
118
+
119
+ ## Orchestrator Integration
120
+
121
+ ### Position in the Flow
122
+
123
+ In `CrewOrchestrator._run_crew`, after agent responses are collected, before final return:
124
+
125
+ ```
126
+ Agent responses collected
127
+ |
128
+ v
129
+ Extract decisions (existing) -> updated_state
130
+ |
131
+ v
132
+ analyze_gaps(responses) -> GapAnalysis
133
+ |
134
+ v
135
+ if has_gaps:
136
+ generate_question_cards(gap_analysis, updated_state) -> list[QuestionCard]
137
+ attach to response
138
+ |
139
+ v
140
+ Check score / auto-trigger plan (existing)
141
+ |
142
+ v
143
+ Return result
144
+ ```
145
+
146
+ ### Modified Response Shape
147
+
148
+ ```json
149
+ {
150
+ "responses": [...],
151
+ "preview": null,
152
+ "design_state": {...},
153
+ "question_cards": [
154
+ {
155
+ "category": "material",
156
+ "question": "What material should this be made from?",
157
+ "responsible_agent": "engineering",
158
+ "agent_name": "Engineering Agent",
159
+ "agent_color": "#00b4d8",
160
+ "suggestions": ["Aluminum 6061", "Aluminum 7075", "Steel 304", "Brass"],
161
+ "allow_custom": true
162
+ },
163
+ {
164
+ "category": "dimension",
165
+ "question": "What are the part dimensions?",
166
+ "responsible_agent": "engineering",
167
+ "agent_name": "Engineering Agent",
168
+ "agent_color": "#00b4d8",
169
+ "suggestions": [],
170
+ "allow_custom": true
171
+ }
172
+ ]
173
+ }
174
+ ```
175
+
176
+ `question_cards` is an empty list when no gaps exist.
177
+
178
+ ### Interaction with Planning Phase
179
+
180
+ - **`exploring` phase:** cards are generated normally.
181
+ - **`approved` phase:** if CAD/CNC/CAM say NOT READY, phase resets to `exploring` AND cards are generated from the gaps — the user sees both the reset and what to fix.
182
+ - **`planning` phase:** no cards (user is reviewing the plan, not chatting).
183
+
184
+ ## Frontend Question Cards
185
+
186
+ ### Layout
187
+
188
+ Rendered inline in the chat, after agent messages:
189
+
190
+ ```
191
+ +------------------------------+
192
+ | MISSING INFO |
193
+ | |
194
+ | EA What material? |
195
+ | [Aluminum 6061] [Alu 7075] |
196
+ | [Steel 304] [Brass] |
197
+ | [Custom: ___________] |
198
+ | |
199
+ | EA Part dimensions? |
200
+ | Width: [____] mm |
201
+ | Height: [____] mm |
202
+ | Depth: [____] mm |
203
+ | [Submit] |
204
+ | |
205
+ +------------------------------+
206
+ ```
207
+
208
+ ### Card Behavior
209
+
210
+ - **Chip-based cards** (material, shape, features, machining, finish, constraint): clicking a chip immediately sends the value through `sendMessage()` as a natural language message. Cards are removed after submission.
211
+ - **Dimension cards:** render input fields (width/height/depth). A "Submit" button sends all dimension values at once as a composed message (e.g., "60mm wide, 40mm high, 20mm deep"). Cards are removed after submission.
212
+ - **Informational cards** (model category): no interaction — just a message explaining what's needed.
213
+ - Only one set of question cards is active at a time. New cards from a subsequent turn replace previous ones.
214
+ - Cards are removed on any `sendMessage()` call — whether the user interacts with a card or types freely in the chat input.
215
+
216
+ ### Styling
217
+
218
+ - Reuses existing `.wizard-chip`, `.wizard-dim-input` classes for consistency with the guided wizard.
219
+ - New `.gap-card` container class with a left border colored by the responsible agent's color.
220
+ - Agent avatar dot shown next to the agent name in each card.
221
+
222
+ ### Client-Side State Update
223
+
224
+ When the user clicks a suggestion or submits dimensions:
225
+ 1. Update `designState` immediately on the client side (same as the wizard does).
226
+ 2. Send the composed message through `sendMessage()`.
227
+ 3. Normal crew routing handles it — no special routing.
228
+
229
+ ## Configuration
230
+
231
+ ### New `gap_analysis` section in `config.yaml`
232
+
233
+ ```yaml
234
+ gap_analysis:
235
+ category_keywords:
236
+ dimension:
237
+ - width
238
+ - height
239
+ - depth
240
+ - length
241
+ - diameter
242
+ - dimension
243
+ - size
244
+ material:
245
+ - material
246
+ - alloy
247
+ - grade
248
+ - aluminum
249
+ - steel
250
+ - metal
251
+ shape:
252
+ - shape
253
+ - form
254
+ - type
255
+ - profile
256
+ - geometry
257
+ - what kind
258
+ feature:
259
+ - hole
260
+ - fillet
261
+ - chamfer
262
+ - pocket
263
+ - slot
264
+ - feature
265
+ constraint:
266
+ - tolerance
267
+ - wall thickness
268
+ - constraint
269
+ - min wall
270
+ - max size
271
+ machining:
272
+ - axis
273
+ - machine
274
+ - setup
275
+ - fixture
276
+ - tool access
277
+ finish:
278
+ - surface finish
279
+ - roughness
280
+ - Ra
281
+ model:
282
+ - model
283
+ - CAD
284
+ - 3D
285
+ - generate
286
+ category_agents:
287
+ dimension: engineering
288
+ material: engineering
289
+ shape: design
290
+ feature: design
291
+ constraint: engineering
292
+ machining: cnc
293
+ finish: cnc
294
+ model: cad
295
+ ```
296
+
297
+ ### Pydantic Config Model
298
+
299
+ ```python
300
+ class GapAnalysisConfig(BaseModel):
301
+ category_keywords: dict[str, list[str]] = Field(default_factory=dict)
302
+ category_agents: dict[str, str] = Field(default_factory=dict)
303
+ ```
304
+
305
+ Added to `Settings` alongside existing `planning` field.
306
+
307
+ ## Files Changed
308
+
309
+ | File | Change |
310
+ |------|--------|
311
+ | `agents/gap_analyzer.py` | **New file.** `MissingItem`, `GapAnalysis`, `QuestionCard` models. `analyze_gaps()` and `generate_question_cards()` functions. Question templates. |
312
+ | `agents/crew_orchestrator.py` | Import gap analyzer. Call `analyze_gaps()` after response collection. Call `generate_question_cards()` if gaps found. Add `question_cards` to return dict. Update CNC/CAM task descriptions with NOT READY protocol. |
313
+ | `config/settings.py` | Add `GapAnalysisConfig` model, add `gap_analysis` field to `Settings`. |
314
+ | `config.yaml` | Add `gap_analysis` section. Update CNC and CAM agent backstories with NOT READY instructions. |
315
+ | `web/index.html` | Add `.gap-card` CSS. Add `renderQuestionCards()` JS function. Update `sendMessage()` to render cards when present. Add card interaction handlers (chip click, dimension submit). |
316
+ | `tests/test_gap_analyzer.py` | **New file.** Tests for `analyze_gaps()`, `generate_question_cards()`, deduplication, state filtering. |
317
+
318
+ ## Files NOT Changed
319
+
320
+ | File | Reason |
321
+ |------|--------|
322
+ | `agents/design_state.py` | Gap analysis is separate from state accumulation |
323
+ | `server/routes.py` | No new endpoints — cards flow through existing `/api/chat` response |
324
+ | `server/web.py` | No new serving needs |
325
+ | `core/executor.py` | Unchanged |
326
+ | `core/cam.py` | Unchanged |
327
+
328
+ ## Testing Strategy
329
+
330
+ - **Unit tests for `analyze_gaps()`** — verify NOT READY detection, keyword categorization, deduplication across agents, handling of responses without NOT READY prefix.
331
+ - **Unit tests for `generate_question_cards()`** — verify correct question/suggestion templates per category, filtering against populated DesignState fields, agent metadata lookup.
332
+ - **Integration test** — verify that a `chat_turn` with a CAD agent returning NOT READY produces `question_cards` in the response alongside agent messages.
333
+ - **Frontend manual testing** — verify cards render after NOT READY response, chip clicks send messages, dimension submit works, cards are removed after interaction.