@thispointon/kondi-chat 0.1.2

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 (108) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +556 -0
  3. package/bin/kondi-chat +56 -0
  4. package/bin/kondi-chat.js +72 -0
  5. package/package.json +55 -0
  6. package/scripts/demo.tape +49 -0
  7. package/scripts/postinstall.cjs +103 -0
  8. package/src/audit/analytics.ts +261 -0
  9. package/src/audit/ledger.ts +253 -0
  10. package/src/audit/telemetry.ts +165 -0
  11. package/src/cli/backend.ts +675 -0
  12. package/src/cli/commands.ts +419 -0
  13. package/src/cli/help.ts +182 -0
  14. package/src/cli/submit-helpers.ts +159 -0
  15. package/src/cli/submit.ts +539 -0
  16. package/src/cli/wizard.ts +121 -0
  17. package/src/context/bootstrap.ts +138 -0
  18. package/src/context/budget.ts +100 -0
  19. package/src/context/manager.ts +666 -0
  20. package/src/context/memory.ts +160 -0
  21. package/src/context/preflight.ts +176 -0
  22. package/src/context/project-brain.ts +101 -0
  23. package/src/context/receipts.ts +108 -0
  24. package/src/context/skills.ts +154 -0
  25. package/src/context/symbol-index.ts +240 -0
  26. package/src/council/profiles.ts +137 -0
  27. package/src/council/tool.ts +138 -0
  28. package/src/council-engine/cli/council-artifacts.ts +230 -0
  29. package/src/council-engine/cli/council-config.ts +178 -0
  30. package/src/council-engine/cli/council-session-export.ts +116 -0
  31. package/src/council-engine/cli/kondi.ts +98 -0
  32. package/src/council-engine/cli/llm-caller.ts +229 -0
  33. package/src/council-engine/cli/localStorage-shim.ts +119 -0
  34. package/src/council-engine/cli/node-platform.ts +68 -0
  35. package/src/council-engine/cli/run-council.ts +481 -0
  36. package/src/council-engine/cli/run-pipeline.ts +772 -0
  37. package/src/council-engine/cli/session-export.ts +153 -0
  38. package/src/council-engine/configs/councils/analysis.json +101 -0
  39. package/src/council-engine/configs/councils/code-planning.json +86 -0
  40. package/src/council-engine/configs/councils/coding.json +89 -0
  41. package/src/council-engine/configs/councils/debate.json +97 -0
  42. package/src/council-engine/configs/councils/solo-claude.json +34 -0
  43. package/src/council-engine/configs/councils/solo-gpt.json +34 -0
  44. package/src/council-engine/council/coding-orchestrator.ts +1205 -0
  45. package/src/council-engine/council/context-bootstrap.ts +147 -0
  46. package/src/council-engine/council/context-inspection.ts +42 -0
  47. package/src/council-engine/council/context-store.ts +763 -0
  48. package/src/council-engine/council/deliberation-orchestrator.ts +2762 -0
  49. package/src/council-engine/council/factory.ts +164 -0
  50. package/src/council-engine/council/index.ts +201 -0
  51. package/src/council-engine/council/ledger-store.ts +438 -0
  52. package/src/council-engine/council/prompts.ts +1689 -0
  53. package/src/council-engine/council/storage-cleanup.ts +164 -0
  54. package/src/council-engine/council/store.ts +1110 -0
  55. package/src/council-engine/council/synthesis.ts +291 -0
  56. package/src/council-engine/council/types.ts +845 -0
  57. package/src/council-engine/council/validation.ts +613 -0
  58. package/src/council-engine/pipeline/build-detect.ts +73 -0
  59. package/src/council-engine/pipeline/executor.ts +1048 -0
  60. package/src/council-engine/pipeline/index.ts +9 -0
  61. package/src/council-engine/pipeline/install-detect.ts +84 -0
  62. package/src/council-engine/pipeline/memory-store.ts +182 -0
  63. package/src/council-engine/pipeline/output-parsers.ts +146 -0
  64. package/src/council-engine/pipeline/run-output.ts +149 -0
  65. package/src/council-engine/pipeline/session-import.ts +177 -0
  66. package/src/council-engine/pipeline/store.ts +753 -0
  67. package/src/council-engine/pipeline/test-detect.ts +82 -0
  68. package/src/council-engine/pipeline/types.ts +401 -0
  69. package/src/council-engine/services/deliberationSummary.ts +114 -0
  70. package/src/council-engine/tsconfig.json +16 -0
  71. package/src/council-engine/types/mcp.ts +122 -0
  72. package/src/council-engine/utils/filterTools.ts +73 -0
  73. package/src/engine/apply.ts +238 -0
  74. package/src/engine/checkpoints.ts +237 -0
  75. package/src/engine/consultants.ts +347 -0
  76. package/src/engine/diff.ts +171 -0
  77. package/src/engine/errors.ts +102 -0
  78. package/src/engine/git-tools.ts +246 -0
  79. package/src/engine/hooks.ts +181 -0
  80. package/src/engine/loop-guard.ts +155 -0
  81. package/src/engine/permissions.ts +293 -0
  82. package/src/engine/pipeline.ts +376 -0
  83. package/src/engine/sub-agents.ts +133 -0
  84. package/src/engine/task-card.ts +185 -0
  85. package/src/engine/task-router.ts +256 -0
  86. package/src/engine/task-store.ts +86 -0
  87. package/src/engine/tools.ts +783 -0
  88. package/src/engine/verify.ts +111 -0
  89. package/src/mcp/client.ts +225 -0
  90. package/src/mcp/config.ts +120 -0
  91. package/src/mcp/tool-manager.ts +192 -0
  92. package/src/mcp/types.ts +61 -0
  93. package/src/providers/llm-caller.ts +943 -0
  94. package/src/providers/rate-limiter.ts +238 -0
  95. package/src/router/NOTES.md +28 -0
  96. package/src/router/collector.ts +474 -0
  97. package/src/router/embeddings.ts +286 -0
  98. package/src/router/index.ts +299 -0
  99. package/src/router/intent-router.ts +225 -0
  100. package/src/router/nn-router.ts +205 -0
  101. package/src/router/profiles.ts +309 -0
  102. package/src/router/registry.ts +565 -0
  103. package/src/router/rules.ts +274 -0
  104. package/src/router/train.py +408 -0
  105. package/src/session/store.ts +211 -0
  106. package/src/test-utils/mock-llm.ts +39 -0
  107. package/src/types.ts +322 -0
  108. package/src/web/manager.ts +311 -0
@@ -0,0 +1,845 @@
1
+ /**
2
+ * Council: Multi-Model Deliberation System
3
+ * Core type definitions
4
+ */
5
+
6
+ export type { ContextInspection } from './context-inspection';
7
+
8
+ // ============================================================================
9
+ // Persona Types
10
+ // ============================================================================
11
+
12
+ export interface Predisposition {
13
+ /** Core identity prompt defining the persona's role and behavior */
14
+ systemPrompt: string;
15
+
16
+ /** The fundamental stance this persona takes */
17
+ stance: 'advocate' | 'critic' | 'neutral' | 'wildcard';
18
+
19
+ /** What this persona champions and argues for */
20
+ arguesFor?: string;
21
+
22
+ /** What this persona pushes back on */
23
+ arguesAgainst?: string;
24
+
25
+ /** Personality traits that guide behavior */
26
+ traits: string[];
27
+
28
+ /** How this persona engages with others */
29
+ interactionStyle: 'debate' | 'build' | 'question' | 'synthesize' | 'review';
30
+
31
+ /** Optional domain expertise */
32
+ domain?: string;
33
+ }
34
+
35
+ export interface Persona {
36
+ id: string;
37
+ name: string;
38
+
39
+ /** Which LLM provider powers this persona */
40
+ provider: string;
41
+
42
+ /** Model ID (e.g., "claude-opus-4", "gpt-4o") */
43
+ model: string;
44
+
45
+ /** The attitude/predisposition defining behavior */
46
+ predisposition: Predisposition;
47
+
48
+ /** Visual identity - URL or emoji */
49
+ avatar?: string;
50
+
51
+ /** Hex color for UI theming */
52
+ color: string;
53
+
54
+ /** Temperature 0-1, higher = more creative/random */
55
+ temperature?: number;
56
+
57
+ /** Response length preference */
58
+ verbosity: 'concise' | 'balanced' | 'thorough';
59
+
60
+ /** Whether this persona is currently muted */
61
+ muted?: boolean;
62
+
63
+ /** Preferred role in deliberation mode (optional hint) */
64
+ preferredDeliberationRole?: 'manager' | 'consultant' | 'worker' | 'reviewer';
65
+
66
+ /** MCP servers this persona can access (undefined = all servers) */
67
+ allowedServerIds?: string[];
68
+ }
69
+
70
+ export interface PresetPersona {
71
+ name: string;
72
+ defaultProvider: string;
73
+ defaultModel: string;
74
+ color: string;
75
+ avatar?: string;
76
+ temperature?: number;
77
+ verbosity?: 'concise' | 'balanced' | 'thorough';
78
+ predisposition: Predisposition;
79
+ }
80
+
81
+ // ============================================================================
82
+ // Council Types
83
+ // ============================================================================
84
+
85
+ export interface Document {
86
+ id: string;
87
+ name: string;
88
+ type: 'text' | 'pdf' | 'image' | 'data';
89
+ content: string;
90
+ }
91
+
92
+ export interface SharedContext {
93
+ /** Text description of the situation being discussed */
94
+ description: string;
95
+
96
+ /** Attached files/documents all personas can see */
97
+ documents: Document[];
98
+
99
+ /** Structured data available to all personas */
100
+ data?: Record<string, unknown>;
101
+
102
+ /** Constraints or requirements to consider */
103
+ constraints?: string[];
104
+ }
105
+
106
+ export type CouncilMode =
107
+ | 'debate' // Personas argue opposing positions
108
+ | 'build' // Personas collaborate, adding to each other
109
+ | 'review' // One presents, others critique
110
+ | 'synthesis' // Each offers perspective, then combine
111
+ | 'socratic' // One questions, others defend
112
+ | 'freeform' // No structure, natural conversation
113
+ | 'deliberation'; // Structured Manager → Consultants → Worker workflow
114
+
115
+ export type TurnStrategy =
116
+ | 'round-robin' // Each speaks in fixed order
117
+ | 'react' // Respond to previous speaker
118
+ | 'popcorn' // Speaker chooses next speaker
119
+ | 'volunteer' // Personas decide if they have something to add
120
+ | 'moderator' // User directs who speaks
121
+ | 'parallel' // All respond simultaneously
122
+ | 'relevance'; // System picks most relevant voice
123
+
124
+ export interface OrchestrationConfig {
125
+ /** Primary interaction pattern */
126
+ mode: CouncilMode;
127
+
128
+ /** How turns are allocated */
129
+ turnStrategy: TurnStrategy;
130
+
131
+ /** Max turns before synthesis/checkpoint */
132
+ maxTurnsPerRound: number;
133
+
134
+ /** Hard stop for total turns */
135
+ maxTotalTurns?: number;
136
+
137
+ /** Generate synthesis after each round */
138
+ autoSynthesize: boolean;
139
+
140
+ /** Which persona synthesizes (or "system") */
141
+ synthesizerId?: string;
142
+
143
+ /** Natural language criteria for convergence */
144
+ convergenceCriteria?: string;
145
+
146
+ /** Must end with clear decision/output */
147
+ requiresResolution: boolean;
148
+ }
149
+
150
+ export interface Council {
151
+ id: string;
152
+ name: string;
153
+ createdAt: string;
154
+ updatedAt: string;
155
+
156
+ /** What's being discussed */
157
+ topic: string;
158
+
159
+ /** Shared context for all personas */
160
+ sharedContext: SharedContext;
161
+
162
+ /** Participating personas */
163
+ personas: Persona[];
164
+
165
+ /** How personas interact */
166
+ orchestration: OrchestrationConfig;
167
+
168
+ /** The conversation (used in non-deliberation modes) */
169
+ messages: CouncilMessage[];
170
+
171
+ /** Current state */
172
+ status: 'active' | 'paused' | 'resolved';
173
+
174
+ /** Final resolution if resolved */
175
+ resolution?: Resolution;
176
+
177
+ /** Usage metrics */
178
+ totalTokensUsed: number;
179
+ estimatedCost: number;
180
+
181
+ /** Deliberation configuration (only when mode === 'deliberation') */
182
+ deliberation?: DeliberationConfig;
183
+
184
+ /** Runtime deliberation state (only when mode === 'deliberation') */
185
+ deliberationState?: DeliberationState;
186
+
187
+ /** Pipeline ID if this council was created by a pipeline step */
188
+ pipelineId?: string;
189
+ }
190
+
191
+ // ============================================================================
192
+ // Message Types
193
+ // ============================================================================
194
+
195
+ export interface Claim {
196
+ id: string;
197
+ text: string;
198
+ type: 'assertion' | 'question' | 'proposal' | 'objection';
199
+ supportedBy?: string[];
200
+ opposedBy?: string[];
201
+ }
202
+
203
+ export interface CouncilMessage {
204
+ id: string;
205
+ timestamp: string;
206
+
207
+ /** Who said it - Persona ID, "user", or "system" */
208
+ speakerId: string;
209
+ speakerType: 'persona' | 'user' | 'system';
210
+
211
+ /** Message content */
212
+ content: string;
213
+
214
+ /** Message being responded to */
215
+ replyingTo?: string;
216
+
217
+ /** For branched conversations */
218
+ threadId?: string;
219
+
220
+ /** Semantic metadata (can be LLM-generated) */
221
+ sentiment?: 'agree' | 'disagree' | 'partial' | 'neutral' | 'question';
222
+
223
+ /** Brief summary of position taken */
224
+ stance?: string;
225
+
226
+ /** How strongly held (0-1) */
227
+ confidence?: number;
228
+
229
+ /** Claims made in this message */
230
+ claims?: Claim[];
231
+
232
+ /** Token usage for this message */
233
+ tokensUsed: number;
234
+
235
+ /** Response latency */
236
+ latencyMs: number;
237
+ }
238
+
239
+ export interface Resolution {
240
+ /** Summary of the deliberation */
241
+ summary: string;
242
+
243
+ /** Consensus level 0-1 */
244
+ consensusLevel: number;
245
+
246
+ /** Key decisions reached */
247
+ keyDecisions: string[];
248
+
249
+ /** Areas of agreement */
250
+ agreements?: string[];
251
+
252
+ /** Key tensions identified */
253
+ tensions?: string[];
254
+
255
+ /** Unresolved disagreements */
256
+ dissent?: string[];
257
+
258
+ /** Recommended next steps */
259
+ nextSteps?: string[];
260
+
261
+ /** Who generated this resolution */
262
+ generatedBy: string;
263
+ }
264
+
265
+ // ============================================================================
266
+ // Event Types
267
+ // ============================================================================
268
+
269
+ export type CouncilEvent =
270
+ | { type: 'persona-added'; persona: Persona }
271
+ | { type: 'persona-removed'; personaId: string }
272
+ | { type: 'persona-muted'; personaId: string }
273
+ | { type: 'persona-unmuted'; personaId: string }
274
+ | { type: 'turn-started'; personaId: string }
275
+ | { type: 'turn-chunk'; personaId: string; content: string }
276
+ | { type: 'turn-completed'; message: CouncilMessage }
277
+ | { type: 'synthesis-started'; synthesizerId: string }
278
+ | { type: 'synthesis-generated'; resolution: Resolution }
279
+ | { type: 'consensus-updated'; level: number }
280
+ | { type: 'council-resolved'; resolution: Resolution }
281
+ | { type: 'council-paused' }
282
+ | { type: 'council-resumed' }
283
+ | { type: 'error'; error: string };
284
+
285
+ // ============================================================================
286
+ // Cost Estimation Types
287
+ // ============================================================================
288
+
289
+ export interface CostEstimate {
290
+ inputTokens: number;
291
+ outputTokens: number;
292
+ estimatedCost: number;
293
+ model: string;
294
+ }
295
+
296
+ export interface RoundCostEstimate {
297
+ personas: Array<{
298
+ personaId: string;
299
+ personaName: string;
300
+ estimate: CostEstimate;
301
+ }>;
302
+ synthesis?: CostEstimate;
303
+ total: number;
304
+ }
305
+
306
+ // ============================================================================
307
+ // Turn Context Types
308
+ // ============================================================================
309
+
310
+ export interface TurnContext {
311
+ /** Recent messages for context */
312
+ recentMessages: CouncilMessage[];
313
+
314
+ /** Current topic being discussed */
315
+ currentTopic: string;
316
+
317
+ /** Unanswered questions */
318
+ openQuestions: string[];
319
+
320
+ /** User's direction for this turn */
321
+ speakerInstruction?: string;
322
+
323
+ /** Previous speaker (for react strategy) */
324
+ previousSpeaker?: Persona;
325
+ }
326
+
327
+ // ============================================================================
328
+ // API Request/Response Types
329
+ // ============================================================================
330
+
331
+ export interface CreateCouncilRequest {
332
+ name: string;
333
+ topic: string;
334
+ sharedContext?: Partial<SharedContext>;
335
+ personas?: Array<Partial<Persona> & { templateId?: string }>;
336
+ orchestration?: Partial<OrchestrationConfig>;
337
+ }
338
+
339
+ export interface AddPersonaRequest {
340
+ templateId?: string;
341
+ persona?: Partial<Persona>;
342
+ }
343
+
344
+ export interface SendMessageRequest {
345
+ content: string;
346
+ replyingTo?: string;
347
+ }
348
+
349
+ export interface AskPersonaRequest {
350
+ personaId: string;
351
+ question: string;
352
+ }
353
+
354
+ export interface DebateRequest {
355
+ personaIds: [string, string];
356
+ topic?: string;
357
+ }
358
+
359
+ export interface SteelmanRequest {
360
+ askingPersonaId: string;
361
+ targetPersonaId: string;
362
+ }
363
+
364
+ // ============================================================================
365
+ // UI State Types
366
+ // ============================================================================
367
+
368
+ export interface CouncilViewState {
369
+ selectedPersonaId: string | null;
370
+ isAddingPersona: boolean;
371
+ isGeneratingTurn: boolean;
372
+ isGeneratingSynthesis: boolean;
373
+ showArgumentMap: boolean;
374
+ showPositionSpectrum: boolean;
375
+ streamingContent: Map<string, string>;
376
+ }
377
+
378
+ export interface PersonaPosition {
379
+ personaId: string;
380
+ position: number; // -1 to 1 on spectrum
381
+ label: string;
382
+ confidence: number;
383
+ }
384
+
385
+ export interface ArgumentNode {
386
+ id: string;
387
+ claimId: string;
388
+ text: string;
389
+ type: 'for' | 'against' | 'modify';
390
+ personaId: string;
391
+ children: ArgumentNode[];
392
+ }
393
+
394
+ export interface ArgumentMap {
395
+ rootClaim: string;
396
+ nodes: ArgumentNode[];
397
+ }
398
+
399
+ // ============================================================================
400
+ // Deliberation Types - Structured Multi-Agent Workflow
401
+ // ============================================================================
402
+
403
+ /**
404
+ * Deliberation roles define behavior and authority.
405
+ * Personas define style, model choice, and personality.
406
+ * Both are assigned per session.
407
+ */
408
+ export type DeliberationRole = 'manager' | 'consultant' | 'worker' | 'reviewer';
409
+
410
+ /**
411
+ * Ledger entry types - structured messaging for audit trail
412
+ */
413
+ export type LedgerEntryType =
414
+ | 'problem_statement' // Manager frames problem → creates Context v1
415
+ | 'analysis' // Consultant round 1 (independent)
416
+ | 'proposal' // Consultant proposes context change
417
+ | 'response' // Consultant round 2+ (engaging others, no context change)
418
+ | 'context_acceptance' // Manager accepts a context patch → new Context version
419
+ | 'context_rejection' // Manager rejects a context patch
420
+ | 'manager_question' // Manager injects question between rounds
421
+ | 'manager_redirect' // Manager refocuses discussion
422
+ | 'round_summary' // Progressive summarization
423
+ | 'decision' // Manager's final decision → Decision artifact
424
+ | 'plan' // Optional execution plan → Plan artifact
425
+ | 'work_directive' // Concrete task for Worker → Directive artifact
426
+ | 'work_output' // Worker's deliverable → Output artifact
427
+ | 'review' // Manager reviews output
428
+ | 'revision_request' // Manager sends back for revision
429
+ | 're_deliberation' // Manager requests re-deliberation with new info
430
+ | 'cancellation' // Workflow cancelled
431
+ | 'error' // Agent invocation error
432
+ // Coding orchestrator entry types
433
+ | 'decomposition' // Manager's module breakdown
434
+ | 'module_directive' // Per-module directive
435
+ | 'module_output' // Per-module worker output
436
+ | 'code_review' // Reviewer's findings
437
+ | 'test_result' // Test command output
438
+ | 'debug_fix'; // Debugger's targeted fix
439
+
440
+ /**
441
+ * Workflow phases - deterministic state machine
442
+ */
443
+ export type DeliberationPhase =
444
+ | 'created' // Workflow created, not started
445
+ | 'problem_framing' // Manager framing the problem
446
+ | 'round_independent' // Round 1: consultants working independently
447
+ | 'round_interactive' // Round 2+: consultants engaging with each other
448
+ | 'round_waiting_for_manager' // All consultants submitted, Manager evaluating
449
+ | 'planning' // Optional: Manager writing execution plan
450
+ | 'deciding' // Manager writing decision
451
+ | 'directing' // Manager writing work directive
452
+ | 'executing' // Worker executing
453
+ | 'reviewing' // Manager reviewing output
454
+ | 'revising' // Worker revising based on feedback
455
+ // Coding orchestrator phases
456
+ | 'decomposing' // Manager decomposes spec into modules
457
+ | 'implementing' // Workers implement modules in parallel
458
+ | 'code_reviewing' // Reviewer reviews all worker output
459
+ | 'testing' // Running test command
460
+ | 'debugging' // Debugger worker fixing test failures
461
+ // Terminal states
462
+ | 'paused' // User paused without losing state
463
+ | 'completed' // Workflow done
464
+ | 'cancelled' // User aborted
465
+ | 'failed'; // Unrecoverable error
466
+
467
+ /**
468
+ * Artifact types - versioned objects referenced by ledger entries
469
+ */
470
+ export type ArtifactType =
471
+ | 'context' // Shared understanding document
472
+ | 'decision' // Manager's decision with rationale
473
+ | 'plan' // Optional breakdown of how to execute
474
+ | 'directive' // Concrete task for Worker
475
+ | 'output'; // Worker's deliverable
476
+
477
+ /**
478
+ * Reference to an artifact from a ledger entry
479
+ */
480
+ export interface ArtifactRef {
481
+ artifactType: ArtifactType;
482
+ artifactId: string;
483
+ version?: number;
484
+ }
485
+
486
+ /**
487
+ * Context artifact - the canonical shared understanding
488
+ * Version 1 is always the Manager's problem statement.
489
+ * Version 2+ result from accepted consultant proposals.
490
+ */
491
+ export interface ContextArtifact {
492
+ id: string;
493
+ councilId: string;
494
+ version: number; // Increments on each accepted change
495
+ content: string; // The current shared context document
496
+
497
+ createdFromVersion?: number; // Which version this was derived from
498
+ changeSummary: string; // What changed in this version
499
+
500
+ authorRole: DeliberationRole;
501
+ authorPersonaId?: string;
502
+ roundNumber?: number;
503
+
504
+ createdAt: string;
505
+ }
506
+
507
+ /**
508
+ * Decision artifact - Manager's final decision
509
+ */
510
+ export interface DecisionArtifact {
511
+ id: string;
512
+ councilId: string;
513
+ content: string;
514
+ contextVersionAtDecision: number; // Which context version this was made against
515
+ acceptanceCriteria?: string;
516
+ createdAt: string;
517
+ }
518
+
519
+ /**
520
+ * Plan artifact - optional execution breakdown
521
+ */
522
+ export interface PlanArtifact {
523
+ id: string;
524
+ councilId: string;
525
+ content: string;
526
+ decisionId: string;
527
+ createdAt: string;
528
+ }
529
+
530
+ /**
531
+ * Directive artifact - concrete task for Worker
532
+ */
533
+ export interface DirectiveArtifact {
534
+ id: string;
535
+ councilId: string;
536
+ content: string;
537
+ decisionId: string;
538
+ planId?: string;
539
+ createdAt: string;
540
+ }
541
+
542
+ /**
543
+ * Output artifact - Worker's deliverable
544
+ */
545
+ export interface OutputArtifact {
546
+ id: string;
547
+ councilId: string;
548
+ content: string;
549
+ directiveId: string;
550
+ version: number; // For revisions
551
+ isRevision: boolean;
552
+ previousOutputId?: string;
553
+ createdAt: string;
554
+ }
555
+
556
+ /**
557
+ * Context patch - consultant proposal to change shared context
558
+ * Consultants don't modify context directly; they propose changes.
559
+ */
560
+ export interface ContextPatch {
561
+ id: string;
562
+ councilId: string;
563
+ targetContextId: string; // Which context artifact this patches
564
+ baseVersion: number; // The version this patch was written against
565
+
566
+ diff: string; // What to change (structured or natural language)
567
+ rationale: string; // Why this change is needed
568
+
569
+ authorPersonaId: string;
570
+ roundNumber: number;
571
+
572
+ status: 'pending' | 'accepted' | 'rejected';
573
+ reviewedBy?: string; // Manager persona ID
574
+ reviewReason?: string; // Why accepted/rejected
575
+
576
+ createdAt: string;
577
+ reviewedAt?: string;
578
+ }
579
+
580
+ /**
581
+ * Ledger entry - append-only audit trail
582
+ */
583
+ export interface LedgerEntry {
584
+ id: string;
585
+ timestamp: string;
586
+
587
+ authorRole: DeliberationRole;
588
+ authorPersonaId: string;
589
+
590
+ entryType: LedgerEntryType;
591
+ phase: DeliberationPhase;
592
+ roundNumber?: number;
593
+
594
+ content: string; // Human-readable text
595
+ structured?: Record<string, unknown>; // Machine-parseable data
596
+
597
+ artifactRefs?: ArtifactRef[]; // References to artifacts created/modified
598
+ referencedEntries?: string[]; // IDs of prior entries this responds to
599
+
600
+ reviewOutcome?: 'accept' | 'revise' | 're_deliberate';
601
+
602
+ tokensUsed?: number;
603
+ latencyMs?: number;
604
+ error?: string;
605
+ }
606
+
607
+ /**
608
+ * Role assignment - maps persona to deliberation role
609
+ */
610
+ export interface DeliberationRoleAssignment {
611
+ personaId: string;
612
+ role: DeliberationRole;
613
+ focusArea?: string; // Consultant specialization (e.g., "security", "UX")
614
+ stance?: string; // Optional: Consultant's starting position or bias
615
+ suppressPersona?: boolean; // Default: true for Worker, false for others
616
+ writePermissions?: boolean; // Worker: allow disk write operations
617
+ /** Per-role MCP server override (undefined = inherit from step/persona) */
618
+ allowedServerIds?: string[];
619
+ /** Override default tool behavior: 'full' = enable all tools, 'none' = disable tools */
620
+ toolAccess?: 'full' | 'none';
621
+ }
622
+
623
+ /**
624
+ * Manager's structured evaluation output
625
+ */
626
+ export interface ManagerEvaluation {
627
+ action: 'continue' | 'decide' | 'redirect';
628
+ reasoning: string;
629
+ confidence?: number; // 0.0-1.0, optional self-assessment
630
+ missingInformation?: string[]; // What's still unknown
631
+ question?: string; // For 'continue' or 'redirect'
632
+ patchDecisions?: { // Accept/reject pending context patches
633
+ patchId: string;
634
+ accepted: boolean;
635
+ reason: string;
636
+ }[];
637
+ }
638
+
639
+ /**
640
+ * Manager's review verdict
641
+ */
642
+ export interface ManagerReview {
643
+ verdict: 'accept' | 'revise' | 're_deliberate';
644
+ reasoning: string;
645
+ feedback?: string; // Specific revision instructions (if revise)
646
+ newInformation?: string; // What changed (if re_deliberate)
647
+ }
648
+
649
+ /**
650
+ * Code reviewer's verdict on implementation quality
651
+ */
652
+ export interface ReviewVerdict {
653
+ verdict: 'pass' | 'needs_revision';
654
+ issues: Array<{
655
+ module: string;
656
+ severity: 'critical' | 'major' | 'minor';
657
+ description: string;
658
+ suggestion: string;
659
+ }>;
660
+ summary: string;
661
+ }
662
+
663
+ /**
664
+ * Summary mode for managing context window
665
+ */
666
+ export type SummaryMode =
667
+ | 'manager' // Manager writes summary (API call, higher quality)
668
+ | 'automatic' // Orchestrator extracts key points mechanically (no API call)
669
+ | 'hybrid' // Automatic for early rounds, Manager for later rounds
670
+ | 'none'; // No summarization, always full context
671
+
672
+ /**
673
+ * Deliberation configuration
674
+ */
675
+ export interface DeliberationConfig {
676
+ enabled: boolean;
677
+
678
+ roleAssignments: DeliberationRoleAssignment[];
679
+
680
+ minRounds: number; // Default: 1
681
+ maxRounds: number; // Default: 4
682
+ maxRevisions: number; // Default: 3
683
+
684
+ // Working directory for execution
685
+ workingDirectory?: string; // Directory path for task execution
686
+ directoryConstrained?: boolean; // If true, constrain all file operations to this directory
687
+
688
+ // Saved problem/question for deliberation (before starting)
689
+ savedProblem?: string;
690
+
691
+ // Expected output/deliverable description
692
+ expectedOutput?: string; // What the worker should produce at the end
693
+
694
+ // Decision guidance — what should the Manager optimize for?
695
+ decisionCriteria?: string[]; // e.g., ["technical feasibility", "security"]
696
+
697
+ summaryMode: SummaryMode; // Default: 'manager'
698
+ summarizeAfterRound: number; // Default: 2
699
+ contextTokenBudget: number; // Default: 80000
700
+
701
+ consultantErrorPolicy: 'retry' | 'skip' | 'fail'; // Default: 'retry'
702
+ maxRetries: number; // Default: 2
703
+
704
+ requirePlan: boolean; // Default: false
705
+
706
+ /**
707
+ * How consultants execute during a round:
708
+ * - 'parallel': All consultants receive same context, respond simultaneously
709
+ * - 'sequential': Each consultant sees previous consultants' responses
710
+ */
711
+ consultantExecution: 'parallel' | 'sequential'; // Default: 'sequential'
712
+
713
+ /** Whether to save deliberation output to .kondi/outputs */
714
+ saveDeliberation?: boolean;
715
+
716
+ /** Save mode: 'full' writes 3 files, 'abbreviated' writes 1 summary file */
717
+ saveDeliberationMode?: 'full' | 'abbreviated';
718
+
719
+ /** Soft word limit per response — guides LLM to be concise, does not truncate */
720
+ maxWordsPerResponse?: number;
721
+
722
+ // Pipeline step type (informs prompt behavior)
723
+ stepType?: 'council' | 'code_planning' | 'analysis' | 'agent' | 'coding' | 'review' | 'enrich';
724
+
725
+ // Coding orchestrator configuration
726
+ testCommand?: string;
727
+ maxDebugCycles?: number; // default 5
728
+ maxReviewCycles?: number; // default 2
729
+
730
+ /** MCP servers this step/council can access (undefined = all servers) */
731
+ allowedServerIds?: string[];
732
+
733
+ /** Whether to auto-scan workingDirectory for context bootstrapping */
734
+ bootstrapContext?: boolean;
735
+
736
+ /** Enable Anthropic prompt caching for bootstrap context (default: true) */
737
+ enablePromptCaching?: boolean;
738
+
739
+ /** Whether to append consultant findings and worker results to the shared context document.
740
+ * When true, context evolves through the deliberation (v1 → v2 → v3...).
741
+ * When false (default), context stays at v1 and findings only live in the ledger. */
742
+ evolveContext?: boolean;
743
+ }
744
+
745
+ /**
746
+ * Deliberation state - runtime workflow state
747
+ */
748
+ export interface DeliberationState {
749
+ currentPhase: DeliberationPhase;
750
+ previousPhase?: DeliberationPhase; // For pause/resume
751
+ currentRound: number;
752
+ roundRunId: string; // Unique ID per round execution
753
+
754
+ maxRounds: number;
755
+ revisionCount: number;
756
+ maxRevisions: number;
757
+
758
+ roundSubmissions: Record<number, string[]>; // round → persona IDs that submitted
759
+ roundSummaries: Record<number, string>;
760
+
761
+ activeContextId: string; // Current context artifact ID
762
+ activeContextVersion: number; // Current context version number
763
+ pendingPatches: string[]; // IDs of unreviewed context patches
764
+
765
+ managerLastEvaluation?: ManagerEvaluation;
766
+
767
+ finalDecisionId?: string; // Decision artifact ID
768
+ workDirectiveId?: string; // Directive artifact ID
769
+ currentOutputId?: string; // Current output artifact ID
770
+
771
+ reDeliberationCount?: number;
772
+
773
+ errorLog: string[];
774
+
775
+ /** Summary generated on completion for the Decision panel */
776
+ completionSummary?: string;
777
+
778
+ // Coding orchestrator state
779
+ moduleDecomposition?: {
780
+ modules: Array<{
781
+ name: string;
782
+ files: string[];
783
+ interfaces: string;
784
+ dependencies: string[];
785
+ directive: string;
786
+ assignedWorkerId?: string;
787
+ }>;
788
+ integrationNotes: string;
789
+ testStrategy: string;
790
+ buildCommand?: string;
791
+ installCommand?: string;
792
+ };
793
+ moduleOutputs?: Record<string, string>; // moduleName -> output content
794
+ debugCycleCount?: number;
795
+ reviewCycleCount?: number;
796
+ }
797
+
798
+ /**
799
+ * Ledger index for chunked storage
800
+ */
801
+ export interface LedgerIndex {
802
+ councilId: string;
803
+ entryCount: number;
804
+ chunkCount: number;
805
+ chunkBoundaries: number[]; // Entry indices where chunks start
806
+ totalTokens: number;
807
+ lastUpdated: string;
808
+ }
809
+
810
+ // ============================================================================
811
+ // Deliberation Events
812
+ // ============================================================================
813
+
814
+ export type DeliberationEvent =
815
+ | { type: 'phase-changed'; from: DeliberationPhase; to: DeliberationPhase }
816
+ | { type: 'round-started'; round: number }
817
+ | { type: 'round-completed'; round: number }
818
+ | { type: 'consultant-submitted'; personaId: string; round: number }
819
+ | { type: 'context-updated'; version: number }
820
+ | { type: 'patch-proposed'; patchId: string; authorId: string }
821
+ | { type: 'patch-reviewed'; patchId: string; accepted: boolean }
822
+ | { type: 'decision-made'; decisionId: string }
823
+ | { type: 'directive-issued'; directiveId: string }
824
+ | { type: 'work-submitted'; outputId: string }
825
+ | { type: 'review-completed'; verdict: string }
826
+ | { type: 'deliberation-completed'; councilId: string }
827
+ | { type: 'deliberation-cancelled'; councilId: string }
828
+ | { type: 'deliberation-failed'; councilId: string; error: string }
829
+ | { type: 'deliberation-paused'; councilId: string }
830
+ | { type: 'deliberation-resumed'; councilId: string };
831
+
832
+ // ============================================================================
833
+ // Extended Council Type for Deliberation
834
+ // ============================================================================
835
+
836
+ /**
837
+ * Extended Council interface with deliberation support
838
+ */
839
+ export interface CouncilWithDeliberation extends Council {
840
+ /** Deliberation configuration (only when mode === 'deliberation') */
841
+ deliberation?: DeliberationConfig;
842
+
843
+ /** Runtime deliberation state */
844
+ deliberationState?: DeliberationState;
845
+ }