analyzthis_design 1.20.1 → 2.0.1

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.
Files changed (173) hide show
  1. package/HOW-TO-USE.md +436 -0
  2. package/README.md +183 -36
  3. package/agents/cards/chunk-planner.md +5 -0
  4. package/agents/cards/mood-board.md +13 -0
  5. package/agents/cards/query-expander.md +17 -0
  6. package/agents/cards/ranker.md +16 -0
  7. package/agents/cards/run-unchunked.md +7 -0
  8. package/agents/chain.json +15 -0
  9. package/agents/manifests/anuj.json +1 -0
  10. package/agents/manifests/arjun.json +1 -0
  11. package/agents/manifests/chunk-planner.json +18 -0
  12. package/agents/manifests/kavi.json +1 -0
  13. package/agents/manifests/meera.json +1 -0
  14. package/agents/manifests/mood-board.json +23 -0
  15. package/agents/manifests/noor.json +1 -0
  16. package/agents/manifests/priya.json +1 -0
  17. package/agents/manifests/query-expander.json +13 -0
  18. package/agents/manifests/raj.json +1 -0
  19. package/agents/manifests/ranker.json +13 -0
  20. package/agents/manifests/run-unchunked.json +19 -0
  21. package/agents/manifests/zara.json +1 -0
  22. package/agents/router.json +14 -0
  23. package/agents/session-schema.json +27 -0
  24. package/dist/.github/ISSUE_TEMPLATE/persona-feedback.yml +75 -0
  25. package/dist/HOW-TO-USE.md +436 -0
  26. package/dist/README.md +869 -0
  27. package/dist/agents/cards/anuj.md +28 -0
  28. package/dist/agents/cards/arjun.md +29 -0
  29. package/dist/agents/cards/chunk-planner.md +5 -0
  30. package/dist/agents/cards/design-director.md +19 -0
  31. package/dist/agents/cards/devi.md +15 -0
  32. package/dist/agents/cards/kavi.md +26 -0
  33. package/dist/agents/cards/meera.md +27 -0
  34. package/dist/agents/cards/mood-board.md +13 -0
  35. package/dist/agents/cards/noor.md +28 -0
  36. package/dist/agents/cards/priya.md +27 -0
  37. package/dist/agents/cards/query-expander.md +17 -0
  38. package/dist/agents/cards/raj.md +29 -0
  39. package/dist/agents/cards/ranker.md +16 -0
  40. package/dist/agents/cards/run-unchunked.md +7 -0
  41. package/dist/agents/cards/zara.md +30 -0
  42. package/dist/agents/chain.json +76 -0
  43. package/dist/agents/deliberation-schema.json +44 -0
  44. package/dist/agents/design-spec-schema.json +111 -0
  45. package/dist/agents/manifests/anuj.json +32 -0
  46. package/dist/agents/manifests/arjun.json +47 -0
  47. package/dist/agents/manifests/chunk-planner.json +18 -0
  48. package/dist/agents/manifests/design-critic.json +21 -0
  49. package/dist/agents/manifests/design-director.json +26 -0
  50. package/dist/agents/manifests/devi.json +31 -0
  51. package/dist/agents/manifests/kavi.json +34 -0
  52. package/dist/agents/manifests/meera.json +32 -0
  53. package/dist/agents/manifests/mood-board.json +23 -0
  54. package/dist/agents/manifests/noor.json +33 -0
  55. package/dist/agents/manifests/persona-orchestrator.json +17 -0
  56. package/dist/agents/manifests/priya.json +32 -0
  57. package/dist/agents/manifests/query-expander.json +13 -0
  58. package/dist/agents/manifests/raj.json +31 -0
  59. package/dist/agents/manifests/ranker.json +13 -0
  60. package/dist/agents/manifests/run-unchunked.json +19 -0
  61. package/dist/agents/manifests/ux-story-gate.json +23 -0
  62. package/dist/agents/manifests/zara.json +33 -0
  63. package/dist/agents/router.json +99 -0
  64. package/dist/agents/session-schema.json +152 -0
  65. package/dist/bin/cli.js +1 -1
  66. package/dist/lib/cache.js +1 -1
  67. package/dist/lib/chunk-executor.js +1 -0
  68. package/dist/lib/chunk-models.js +1 -0
  69. package/dist/lib/chunk-planner.js +1 -0
  70. package/dist/lib/chunk-router.js +1 -0
  71. package/dist/lib/chunk-run.js +1 -0
  72. package/dist/lib/chunk-synthesis.js +1 -0
  73. package/dist/lib/chunk-telemetry.js +1 -0
  74. package/dist/lib/collect.js +1 -1
  75. package/dist/lib/cost.js +1 -1
  76. package/dist/lib/dedup.js +1 -0
  77. package/dist/lib/deliberation.js +1 -1
  78. package/dist/lib/design-spec.js +1 -1
  79. package/dist/lib/evolve.js +1 -0
  80. package/dist/lib/export.js +1 -1
  81. package/dist/lib/feedback-submit.js +1 -1
  82. package/dist/lib/feedback.js +1 -1
  83. package/dist/lib/host-llm.js +1 -1
  84. package/dist/lib/install.js +1 -1
  85. package/dist/lib/knowledge.js +1 -1
  86. package/dist/lib/lessons.js +1 -0
  87. package/dist/lib/moodboard.js +1 -0
  88. package/dist/lib/orchestrator/run.js +1 -1
  89. package/dist/lib/outcome.js +1 -0
  90. package/dist/lib/platforms.js +1 -1
  91. package/dist/lib/provider.js +1 -1
  92. package/dist/lib/query-expander.js +1 -0
  93. package/dist/lib/ranker.js +1 -0
  94. package/dist/lib/reference-pack.js +1 -0
  95. package/dist/lib/research.js +1 -1
  96. package/dist/lib/retrieve.js +1 -1
  97. package/dist/lib/session.js +1 -1
  98. package/dist/lib/source-discovery.js +1 -1
  99. package/dist/lib/synthesis.js +1 -1
  100. package/dist/lib/token-gate.js +1 -1
  101. package/dist/skills/anuj/SKILL.md +92 -0
  102. package/dist/skills/arjun/SKILL.md +291 -0
  103. package/dist/skills/chunk-planner/SKILL.md +45 -0
  104. package/dist/skills/collect-knowledge/SKILL.md +20 -0
  105. package/dist/skills/deliberation-protocol/SKILL.md +131 -0
  106. package/dist/skills/design-critic/SKILL.md +191 -0
  107. package/dist/skills/design-director/SKILL.md +181 -0
  108. package/dist/skills/design-personas/SKILL.md +100 -0
  109. package/dist/skills/design-reference/SKILL.md +83 -0
  110. package/dist/skills/design-reference/app-interface.csv +31 -0
  111. package/dist/skills/design-reference/charts.csv +26 -0
  112. package/dist/skills/design-reference/colors.csv +162 -0
  113. package/dist/skills/design-reference/google-fonts.csv +1924 -0
  114. package/dist/skills/design-reference/icons.csv +106 -0
  115. package/dist/skills/design-reference/landing.csv +35 -0
  116. package/dist/skills/design-reference/products.csv +162 -0
  117. package/dist/skills/design-reference/react-performance.csv +45 -0
  118. package/dist/skills/design-reference/schema.json +159 -0
  119. package/dist/skills/design-reference/stacks/angular.csv +51 -0
  120. package/dist/skills/design-reference/stacks/astro.csv +54 -0
  121. package/dist/skills/design-reference/stacks/flutter.csv +53 -0
  122. package/dist/skills/design-reference/stacks/html-tailwind.csv +56 -0
  123. package/dist/skills/design-reference/stacks/jetpack-compose.csv +53 -0
  124. package/dist/skills/design-reference/stacks/laravel.csv +51 -0
  125. package/dist/skills/design-reference/stacks/nextjs.csv +53 -0
  126. package/dist/skills/design-reference/stacks/nuxt-ui.csv +51 -0
  127. package/dist/skills/design-reference/stacks/nuxtjs.csv +59 -0
  128. package/dist/skills/design-reference/stacks/react-native.csv +52 -0
  129. package/dist/skills/design-reference/stacks/react.csv +54 -0
  130. package/dist/skills/design-reference/stacks/shadcn.csv +61 -0
  131. package/dist/skills/design-reference/stacks/svelte.csv +54 -0
  132. package/dist/skills/design-reference/stacks/swiftui.csv +51 -0
  133. package/dist/skills/design-reference/stacks/threejs.csv +54 -0
  134. package/dist/skills/design-reference/stacks/vue.csv +50 -0
  135. package/dist/skills/design-reference/styles.csv +85 -0
  136. package/dist/skills/design-reference/typography.csv +75 -0
  137. package/dist/skills/design-reference/ui-reasoning.csv +162 -0
  138. package/dist/skills/design-reference/ux-guidelines.csv +100 -0
  139. package/dist/skills/design-spec/SKILL.md +106 -0
  140. package/dist/skills/devi/SKILL.md +114 -0
  141. package/dist/skills/getting-started/SKILL.md +144 -0
  142. package/dist/skills/kavi/SKILL.md +118 -0
  143. package/dist/skills/knowledge-bank/SKILL.md +43 -0
  144. package/dist/skills/meera/SKILL.md +76 -0
  145. package/dist/skills/mood-board/SKILL.md +113 -0
  146. package/dist/skills/noor/SKILL.md +96 -0
  147. package/dist/skills/persona-orchestrator/SKILL.md +220 -0
  148. package/dist/skills/priya/SKILL.md +75 -0
  149. package/dist/skills/raj/SKILL.md +77 -0
  150. package/dist/skills/run-unchunked/SKILL.md +49 -0
  151. package/dist/skills/ux-ideator/SKILL.md +187 -0
  152. package/dist/skills/ux-story-gate/SKILL.md +353 -0
  153. package/dist/skills/zara/SKILL.md +85 -0
  154. package/dist/supabase/deliberation-config.example.json +15 -0
  155. package/dist/supabase/feedback-config.example.json +7 -0
  156. package/dist/supabase/migrations/001_persona_feedback.sql +54 -0
  157. package/package.json +7 -4
  158. package/scripts/validate-csvs.js +197 -0
  159. package/skills/chunk-planner/SKILL.md +45 -0
  160. package/skills/design-reference/google-fonts.csv +1924 -1924
  161. package/skills/design-reference/products.csv +162 -162
  162. package/skills/design-reference/schema.json +159 -0
  163. package/skills/design-reference/stacks/angular.csv +1 -1
  164. package/skills/design-reference/stacks/astro.csv +1 -1
  165. package/skills/design-reference/stacks/laravel.csv +2 -2
  166. package/skills/design-reference/stacks/threejs.csv +54 -54
  167. package/skills/design-reference/styles.csv +85 -85
  168. package/skills/design-reference/typography.csv +75 -74
  169. package/skills/design-reference/ui-reasoning.csv +1 -1
  170. package/skills/getting-started/SKILL.md +12 -0
  171. package/skills/mood-board/SKILL.md +113 -0
  172. package/skills/persona-orchestrator/SKILL.md +35 -1
  173. package/skills/run-unchunked/SKILL.md +49 -0
@@ -0,0 +1,54 @@
1
+ -- Persona feedback — anonymous community corrections for analyzthis_design
2
+ -- Run in Supabase SQL editor or via supabase db push
3
+
4
+ create table if not exists public.persona_feedback (
5
+ id uuid primary key default gen_random_uuid(),
6
+ created_at timestamptz not null default now(),
7
+
8
+ install_id text not null,
9
+ package_version text,
10
+ feedback_id text,
11
+
12
+ persona text not null,
13
+ satisfied boolean not null default false,
14
+ rating smallint check (rating is null or (rating >= 1 and rating <= 5)),
15
+ tags text[] not null default '{}',
16
+
17
+ user_comment text,
18
+ assistant_rejected text,
19
+ assistant_preferred text,
20
+ task_summary text,
21
+ problem_type text,
22
+ mode text,
23
+ recorded_at timestamptz
24
+ );
25
+
26
+ create index if not exists persona_feedback_persona_idx on public.persona_feedback (persona);
27
+ create index if not exists persona_feedback_created_at_idx on public.persona_feedback (created_at desc);
28
+ create index if not exists persona_feedback_tags_idx on public.persona_feedback using gin (tags);
29
+
30
+ alter table public.persona_feedback enable row level security;
31
+
32
+ -- Anonymous clients may INSERT only (no read/update/delete for anon)
33
+ drop policy if exists "anon_insert_persona_feedback" on public.persona_feedback;
34
+ create policy "anon_insert_persona_feedback"
35
+ on public.persona_feedback
36
+ for insert
37
+ to anon
38
+ with check (
39
+ char_length(coalesce(user_comment, '')) <= 2000
40
+ and char_length(coalesce(assistant_rejected, '')) <= 4000
41
+ and char_length(coalesce(assistant_preferred, '')) <= 4000
42
+ and persona ~ '^[a-z][a-z0-9_-]{0,31}$'
43
+ );
44
+
45
+ -- Service role (dashboard) can read everything — use Supabase dashboard or service key
46
+ drop policy if exists "service_read_persona_feedback" on public.persona_feedback;
47
+ create policy "service_read_persona_feedback"
48
+ on public.persona_feedback
49
+ for select
50
+ to service_role
51
+ using (true);
52
+
53
+ comment on table public.persona_feedback is
54
+ 'Anonymous opt-in persona correction data from analyzthis_design CLI (feedback submit).';
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "analyzthis_design",
3
- "version": "1.20.1",
4
- "description": "8 AI design personas — adversarial deliberation loops, opt-in community feedback, Kavi knowledge collection, DesignSpec producer path, wireframe skills, UX critique, Agent Skills for Cursor, Claude, Codex, Grok, Windsurf.",
3
+ "version": "2.0.1",
4
+ "description": "8 AI design personas — v2.0 chunked execution with frontier planner + free/cheap chunk models, adversarial deliberation loops, opt-in community feedback, Kavi knowledge collection, DesignSpec producer path, wireframe skills, UX critique, Agent Skills for Cursor, Claude, Codex, Grok, Windsurf.",
5
5
  "keywords": [
6
6
  "cursor",
7
7
  "cursor-skill",
@@ -35,11 +35,14 @@
35
35
  "agents/",
36
36
  "supabase/",
37
37
  ".github/",
38
- "README.md"
38
+ "scripts/validate-csvs.js",
39
+ "README.md",
40
+ "HOW-TO-USE.md"
39
41
  ],
40
42
  "scripts": {
41
43
  "build": "node scripts/obfuscate.js",
42
- "prepublishOnly": "npm run build",
44
+ "validate": "node scripts/validate-csvs.js",
45
+ "prepublishOnly": "npm run build && npm run validate",
43
46
  "postinstall": "node dist/lib/install.js --silent --welcome"
44
47
  },
45
48
  "engines": {
@@ -0,0 +1,197 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+
4
+ /**
5
+ * CSV validation script.
6
+ *
7
+ * Checks every CSV file in skills/design-reference/ against schema.json:
8
+ * 1. Row cell count matches header column count
9
+ * 2. No column has a No column missing
10
+ * 3. Cross-file joins resolve (e.g. products.csv Mapped Pattern → landing.csv Pattern Name)
11
+ * 4. Filter columns are populated (not empty for majority of rows)
12
+ *
13
+ * Usage: node scripts/validate-csvs.js
14
+ * Exit code: 0 = all pass, 1 = errors found
15
+ */
16
+
17
+ var fs = require('fs');
18
+ var path = require('path');
19
+ var retrieve = require('../lib/retrieve');
20
+
21
+ var REF_DIR = path.join(__dirname, '..', 'skills', 'design-reference');
22
+ var SCHEMA_PATH = path.join(REF_DIR, 'schema.json');
23
+
24
+ function parseCsvLine(line) {
25
+ var cells = [];
26
+ var cur = '';
27
+ var inQuotes = false;
28
+ for (var i = 0; i < line.length; i++) {
29
+ var ch = line[i];
30
+ if (inQuotes) {
31
+ if (ch === '"' && line[i + 1] === '"') { cur += '"'; i++; }
32
+ else if (ch === '"') { inQuotes = false; }
33
+ else { cur += ch; }
34
+ } else if (ch === '"') { inQuotes = true; }
35
+ else if (ch === ',') { cells.push(cur); cur = ''; }
36
+ else { cur += ch; }
37
+ }
38
+ cells.push(cur);
39
+ return cells;
40
+ }
41
+
42
+ function splitCsvRows(text) {
43
+ var rows = [];
44
+ var cur = '';
45
+ var inQuotes = false;
46
+ for (var i = 0; i < text.length; i++) {
47
+ var ch = text[i];
48
+ if (ch === '"') inQuotes = !inQuotes;
49
+ if (ch === '\n' && !inQuotes) { rows.push(cur); cur = ''; }
50
+ else if (ch !== '\r') cur += ch;
51
+ }
52
+ if (cur.trim().length) rows.push(cur);
53
+ return rows;
54
+ }
55
+
56
+ var schema = JSON.parse(fs.readFileSync(SCHEMA_PATH, 'utf8'));
57
+ var errors = [];
58
+ var warnings = [];
59
+
60
+ for (var fileKey in schema.files) {
61
+ var spec = schema.files[fileKey];
62
+ var filePath = path.join(REF_DIR, fileKey);
63
+ if (!fs.existsSync(filePath)) {
64
+ errors.push(fileKey + ': FILE MISSING');
65
+ continue;
66
+ }
67
+
68
+ var content = fs.readFileSync(filePath, 'utf8');
69
+ var rows = splitCsvRows(content);
70
+ var header = parseCsvLine(rows[0]);
71
+ var expectedHeader = spec.header;
72
+
73
+ // Check header matches schema
74
+ if (header.length !== expectedHeader.length) {
75
+ errors.push(fileKey + ': header has ' + header.length + ' columns, schema expects ' + expectedHeader.length);
76
+ } else {
77
+ for (var h = 0; h < header.length; h++) {
78
+ if (header[h].trim() !== expectedHeader[h].trim()) {
79
+ errors.push(fileKey + ': header column ' + h + ' is "' + header[h].trim() + '", schema expects "' + expectedHeader[h].trim() + '"');
80
+ }
81
+ }
82
+ }
83
+
84
+ // Check each data row has the right cell count
85
+ var badRows = 0;
86
+ for (var r = 1; r < rows.length; r++) {
87
+ if (!rows[r].trim()) continue;
88
+ var cells = parseCsvLine(rows[r]);
89
+ if (cells.length !== header.length) {
90
+ badRows++;
91
+ if (badRows <= 3) {
92
+ errors.push(fileKey + ' row ' + (r + 1) + ': ' + cells.length + ' cells (expected ' + header.length + ')');
93
+ }
94
+ }
95
+ }
96
+ if (badRows > 3) {
97
+ errors.push(fileKey + ': ... and ' + (badRows - 3) + ' more row-length mismatches');
98
+ }
99
+
100
+ // Check No column exists
101
+ if (spec.no_column && header.indexOf(spec.no_column) === -1) {
102
+ errors.push(fileKey + ': missing No column "' + spec.no_column + '"');
103
+ }
104
+
105
+ // Check filter column is populated
106
+ if (spec.filter_column) {
107
+ var filterIdx = header.indexOf(spec.filter_column);
108
+ if (filterIdx === -1) {
109
+ errors.push(fileKey + ': filter column "' + spec.filter_column + '" not found in header');
110
+ } else {
111
+ var emptyCount = 0;
112
+ var totalRows = 0;
113
+ for (var r2 = 1; r2 < rows.length; r2++) {
114
+ if (!rows[r2].trim()) continue;
115
+ totalRows++;
116
+ var cells2 = parseCsvLine(rows[r2]);
117
+ if (!cells2[filterIdx] || !cells2[filterIdx].trim()) emptyCount++;
118
+ }
119
+ if (totalRows > 0 && emptyCount / totalRows > 0.3) {
120
+ warnings.push(fileKey + ': filter column "' + spec.filter_column + '" is empty in ' + emptyCount + '/' + totalRows + ' rows (' + Math.round(emptyCount / totalRows * 100) + '%)');
121
+ }
122
+ }
123
+ }
124
+
125
+ // Check cross-file joins
126
+ if (spec.joins) {
127
+ for (var joinCol in spec.joins) {
128
+ var joinSpec = spec.joins[joinCol];
129
+ var joinIdx = header.indexOf(joinCol);
130
+ if (joinIdx === -1) continue;
131
+
132
+ var targetPath = path.join(REF_DIR, joinSpec.target_file);
133
+ if (!fs.existsSync(targetPath)) continue;
134
+ var targetContent = fs.readFileSync(targetPath, 'utf8');
135
+ var targetRows = splitCsvRows(targetContent);
136
+ var targetHeader = parseCsvLine(targetRows[0]);
137
+ var targetColIdx = targetHeader.indexOf(joinSpec.target_column);
138
+ if (targetColIdx === -1) continue;
139
+
140
+ var targetValues = {};
141
+ for (var tr = 1; tr < targetRows.length; tr++) {
142
+ if (!targetRows[tr].trim()) continue;
143
+ var targetCells = parseCsvLine(targetRows[tr]);
144
+ var val = targetCells[targetColIdx];
145
+ if (val) targetValues[val] = true;
146
+ }
147
+
148
+ var joinMisses = 0;
149
+ var joinTotal = 0;
150
+ for (var jr = 1; jr < rows.length; jr++) {
151
+ if (!rows[jr].trim()) continue;
152
+ var joinCells = parseCsvLine(rows[jr]);
153
+ var joinVal = joinCells[joinIdx];
154
+ if (!joinVal || !joinVal.trim()) continue;
155
+ joinTotal++;
156
+ if (!targetValues[joinVal]) joinMisses++;
157
+ }
158
+ if (joinTotal > 0 && joinMisses / joinTotal > 0.2) {
159
+ warnings.push(fileKey + ': join "' + joinCol + '" → ' + joinSpec.target_file + '.' + joinSpec.target_column + ': ' + joinMisses + '/' + joinTotal + ' misses (' + Math.round(joinMisses / joinTotal * 100) + '%)');
160
+ }
161
+ }
162
+ }
163
+
164
+ // Check Docs URL sparseness in stack files
165
+ if (fileKey.indexOf('stacks/') === 0) {
166
+ var docsIdx = header.indexOf('Docs URL');
167
+ if (docsIdx !== -1) {
168
+ var emptyDocs = 0;
169
+ var totalStack = 0;
170
+ for (var dr = 1; dr < rows.length; dr++) {
171
+ if (!rows[dr].trim()) continue;
172
+ totalStack++;
173
+ var docsCells = parseCsvLine(rows[dr]);
174
+ if (!docsCells[docsIdx] || !docsCells[docsIdx].trim()) emptyDocs++;
175
+ }
176
+ if (totalStack > 0 && emptyDocs / totalStack > 0.5) {
177
+ warnings.push(fileKey + ': Docs URL empty in ' + emptyDocs + '/' + totalStack + ' rows');
178
+ }
179
+ }
180
+ }
181
+ }
182
+
183
+ // Report
184
+ if (warnings.length) {
185
+ console.log('\n── Warnings ──');
186
+ warnings.forEach(function(w) { console.log(' ⚠ ' + w); });
187
+ }
188
+
189
+ if (errors.length) {
190
+ console.log('\n── Errors ──');
191
+ errors.forEach(function(e) { console.log(' ✗ ' + e); });
192
+ console.log('\n❌ ' + errors.length + ' error(s), ' + warnings.length + ' warning(s)\n');
193
+ process.exit(1);
194
+ } else {
195
+ console.log('\n✅ All ' + Object.keys(schema.files).length + ' CSV files pass validation (' + warnings.length + ' warning(s))\n');
196
+ process.exit(0);
197
+ }
@@ -0,0 +1,45 @@
1
+ ---
2
+ name: chunk-planner
3
+ description: Explain the chunked execution planner. The planner is a frontier/strong model that breaks a design task into small, sequential chunks and assigns each to the cheapest capable model.
4
+ ---
5
+
6
+ # Chunk Planner
7
+
8
+ In Analyzthis Design v2.0, the default `run` command uses **chunked execution**.
9
+
10
+ ## How it works
11
+
12
+ 1. **Planner** (frontier/strong model) reads the task + knowledge bank once.
13
+ 2. It produces a chunk graph: persona, goal, prompts, effort, and dependencies per chunk.
14
+ 3. **Router** picks the cheapest capable model for each chunk from:
15
+ - Local Ollama models (auto-detected)
16
+ - Free cloud APIs (Groq, Google Gemini, OpenRouter)
17
+ - Cheap cloud APIs (OpenAI GPT-4o-mini, DeepSeek, Together)
18
+ 4. **Executor** runs chunks sequentially by default, with retry + fallback.
19
+ 5. **Synthesis** merges outputs and produces a final verdict.
20
+
21
+ ## Planner policy
22
+
23
+ - The planner **never** runs on a lower/cheap model.
24
+ - If no frontier API key is available, it falls back to the host/Devi model with a warning.
25
+
26
+ ## Example plan
27
+
28
+ ```json
29
+ {
30
+ "chunks": [
31
+ { "id": "ia", "persona": "noor", "effort": "standard", "depends_on": [] },
32
+ { "id": "visual", "persona": "arjun", "effort": "standard", "depends_on": ["ia"] },
33
+ { "id": "feasibility", "persona": "priya", "effort": "trivial", "depends_on": ["ia"] },
34
+ { "id": "synthesis", "persona": "raj", "effort": "hard", "depends_on": ["visual", "feasibility"] }
35
+ ]
36
+ }
37
+ ```
38
+
39
+ ## Inspect a plan without running it
40
+
41
+ ```bash
42
+ npx analyzthis_design run --task "..." --dry-run
43
+ ```
44
+
45
+ This shows the planner output without calling any chunk models.