@lcv-ideas-software/cross-review 4.0.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.
Files changed (122) hide show
  1. package/CHANGELOG.md +2568 -0
  2. package/LICENSE +201 -0
  3. package/NOTICE +26 -0
  4. package/README.md +208 -0
  5. package/SECURITY.md +52 -0
  6. package/dist/scripts/api-streaming-smoke.d.ts +1 -0
  7. package/dist/scripts/api-streaming-smoke.js +78 -0
  8. package/dist/scripts/api-streaming-smoke.js.map +1 -0
  9. package/dist/scripts/runtime-default-smoke.d.ts +1 -0
  10. package/dist/scripts/runtime-default-smoke.js +88 -0
  11. package/dist/scripts/runtime-default-smoke.js.map +1 -0
  12. package/dist/scripts/runtime-smoke.d.ts +1 -0
  13. package/dist/scripts/runtime-smoke.js +148 -0
  14. package/dist/scripts/runtime-smoke.js.map +1 -0
  15. package/dist/scripts/smoke.d.ts +1 -0
  16. package/dist/scripts/smoke.js +6156 -0
  17. package/dist/scripts/smoke.js.map +1 -0
  18. package/dist/src/core/cache-manifest.d.ts +22 -0
  19. package/dist/src/core/cache-manifest.js +133 -0
  20. package/dist/src/core/cache-manifest.js.map +1 -0
  21. package/dist/src/core/caller-tokens.d.ts +32 -0
  22. package/dist/src/core/caller-tokens.js +240 -0
  23. package/dist/src/core/caller-tokens.js.map +1 -0
  24. package/dist/src/core/config.d.ts +9 -0
  25. package/dist/src/core/config.js +643 -0
  26. package/dist/src/core/config.js.map +1 -0
  27. package/dist/src/core/convergence.d.ts +5 -0
  28. package/dist/src/core/convergence.js +186 -0
  29. package/dist/src/core/convergence.js.map +1 -0
  30. package/dist/src/core/cost.d.ts +59 -0
  31. package/dist/src/core/cost.js +359 -0
  32. package/dist/src/core/cost.js.map +1 -0
  33. package/dist/src/core/file-config.d.ts +316 -0
  34. package/dist/src/core/file-config.js +490 -0
  35. package/dist/src/core/file-config.js.map +1 -0
  36. package/dist/src/core/orchestrator.d.ts +199 -0
  37. package/dist/src/core/orchestrator.js +3430 -0
  38. package/dist/src/core/orchestrator.js.map +1 -0
  39. package/dist/src/core/prompt-parts.d.ts +58 -0
  40. package/dist/src/core/prompt-parts.js +122 -0
  41. package/dist/src/core/prompt-parts.js.map +1 -0
  42. package/dist/src/core/relator-lottery.d.ts +23 -0
  43. package/dist/src/core/relator-lottery.js +112 -0
  44. package/dist/src/core/relator-lottery.js.map +1 -0
  45. package/dist/src/core/reports.d.ts +2 -0
  46. package/dist/src/core/reports.js +82 -0
  47. package/dist/src/core/reports.js.map +1 -0
  48. package/dist/src/core/session-store.d.ts +149 -0
  49. package/dist/src/core/session-store.js +1923 -0
  50. package/dist/src/core/session-store.js.map +1 -0
  51. package/dist/src/core/status.d.ts +61 -0
  52. package/dist/src/core/status.js +249 -0
  53. package/dist/src/core/status.js.map +1 -0
  54. package/dist/src/core/timeouts.d.ts +2 -0
  55. package/dist/src/core/timeouts.js +3 -0
  56. package/dist/src/core/timeouts.js.map +1 -0
  57. package/dist/src/core/types.d.ts +604 -0
  58. package/dist/src/core/types.js +36 -0
  59. package/dist/src/core/types.js.map +1 -0
  60. package/dist/src/dashboard/server.d.ts +2 -0
  61. package/dist/src/dashboard/server.js +339 -0
  62. package/dist/src/dashboard/server.js.map +1 -0
  63. package/dist/src/mcp/server.d.ts +54 -0
  64. package/dist/src/mcp/server.js +1584 -0
  65. package/dist/src/mcp/server.js.map +1 -0
  66. package/dist/src/observability/logger.d.ts +9 -0
  67. package/dist/src/observability/logger.js +24 -0
  68. package/dist/src/observability/logger.js.map +1 -0
  69. package/dist/src/peers/anthropic.d.ts +14 -0
  70. package/dist/src/peers/anthropic.js +290 -0
  71. package/dist/src/peers/anthropic.js.map +1 -0
  72. package/dist/src/peers/base.d.ts +72 -0
  73. package/dist/src/peers/base.js +416 -0
  74. package/dist/src/peers/base.js.map +1 -0
  75. package/dist/src/peers/deepseek.d.ts +12 -0
  76. package/dist/src/peers/deepseek.js +246 -0
  77. package/dist/src/peers/deepseek.js.map +1 -0
  78. package/dist/src/peers/errors.d.ts +2 -0
  79. package/dist/src/peers/errors.js +185 -0
  80. package/dist/src/peers/errors.js.map +1 -0
  81. package/dist/src/peers/gemini.d.ts +13 -0
  82. package/dist/src/peers/gemini.js +215 -0
  83. package/dist/src/peers/gemini.js.map +1 -0
  84. package/dist/src/peers/grok.d.ts +17 -0
  85. package/dist/src/peers/grok.js +346 -0
  86. package/dist/src/peers/grok.js.map +1 -0
  87. package/dist/src/peers/model-selection.d.ts +4 -0
  88. package/dist/src/peers/model-selection.js +260 -0
  89. package/dist/src/peers/model-selection.js.map +1 -0
  90. package/dist/src/peers/openai.d.ts +14 -0
  91. package/dist/src/peers/openai.js +299 -0
  92. package/dist/src/peers/openai.js.map +1 -0
  93. package/dist/src/peers/perplexity.d.ts +18 -0
  94. package/dist/src/peers/perplexity.js +375 -0
  95. package/dist/src/peers/perplexity.js.map +1 -0
  96. package/dist/src/peers/registry.d.ts +3 -0
  97. package/dist/src/peers/registry.js +77 -0
  98. package/dist/src/peers/registry.js.map +1 -0
  99. package/dist/src/peers/retry.d.ts +2 -0
  100. package/dist/src/peers/retry.js +36 -0
  101. package/dist/src/peers/retry.js.map +1 -0
  102. package/dist/src/peers/stub.d.ts +13 -0
  103. package/dist/src/peers/stub.js +344 -0
  104. package/dist/src/peers/stub.js.map +1 -0
  105. package/dist/src/peers/text.d.ts +18 -0
  106. package/dist/src/peers/text.js +39 -0
  107. package/dist/src/peers/text.js.map +1 -0
  108. package/dist/src/security/redact.d.ts +2 -0
  109. package/dist/src/security/redact.js +128 -0
  110. package/dist/src/security/redact.js.map +1 -0
  111. package/docs/api-keys.md +34 -0
  112. package/docs/architecture.md +118 -0
  113. package/docs/caching.md +135 -0
  114. package/docs/costs.md +40 -0
  115. package/docs/evidence-preflight.md +88 -0
  116. package/docs/github-security-baseline.md +32 -0
  117. package/docs/model-selection.md +105 -0
  118. package/docs/reports/cross-review-v2-api-capability-smoke-2026-04-30.md +354 -0
  119. package/docs/reports/cross-review-v2-format-recovery-findings-2026-04-28.md +223 -0
  120. package/docs/reports/cross-review-v2-official-provider-docs-refresh-2026-05-05.md +60 -0
  121. package/docs/reports/cross-review-v2-token-streaming-smoke-2026-04-30.md +119 -0
  122. package/package.json +88 -0
@@ -0,0 +1,604 @@
1
+ export declare const PEERS: readonly ["codex", "claude", "gemini", "deepseek", "grok", "perplexity"];
2
+ export type PeerId = (typeof PEERS)[number];
3
+ export declare const STATUSES: readonly ["READY", "NOT_READY", "NEEDS_EVIDENCE"];
4
+ export type ReviewStatus = (typeof STATUSES)[number];
5
+ export type Confidence = "verified" | "inferred" | "unknown";
6
+ export type SessionOutcome = "converged" | "aborted" | "max-rounds";
7
+ export type SessionMode = "ship" | "review" | "circular";
8
+ export type ReasoningEffort = "none" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max";
9
+ export type SessionControlStatus = "running" | "cancel_requested" | "cancelled" | "recovered_after_restart";
10
+ export type DecisionQuality = "clean" | "format_warning" | "recovered" | "needs_operator_review" | "failed";
11
+ export interface ModelCandidate {
12
+ id: string;
13
+ display_name?: string;
14
+ source: "api" | "documented-priority" | "env-override";
15
+ metadata?: Record<string, unknown>;
16
+ }
17
+ export interface ModelSelection {
18
+ peer: PeerId;
19
+ selected: string;
20
+ candidates: ModelCandidate[];
21
+ source_url: string;
22
+ reason: string;
23
+ confidence: Confidence;
24
+ }
25
+ export interface TokenUsage {
26
+ input_tokens?: number;
27
+ output_tokens?: number;
28
+ total_tokens?: number;
29
+ reasoning_tokens?: number;
30
+ cache_read_tokens?: number;
31
+ cache_write_tokens?: number;
32
+ cache_provider_mode?: "auto" | "explicit" | "implicit" | "not_supported";
33
+ cache_key_hash?: string;
34
+ citation_tokens?: number;
35
+ num_search_queries?: number;
36
+ provider_reported_total_cost_usd?: number;
37
+ search_performed?: boolean;
38
+ }
39
+ export interface CostEstimate {
40
+ currency: "USD";
41
+ input_cost?: number;
42
+ output_cost?: number;
43
+ total_cost?: number;
44
+ estimated: boolean;
45
+ source: "configured-rate" | "unknown-rate" | "stub";
46
+ cache_savings_usd?: number;
47
+ cache_savings_unknown?: boolean;
48
+ cache_read_cost?: number;
49
+ cache_write_cost?: number;
50
+ tier_used?: "base" | "extended" | "promo" | "promo_extended";
51
+ request_cost?: number;
52
+ citation_tokens_cost?: number;
53
+ deep_research_reasoning_tokens_cost?: number;
54
+ search_queries_cost?: number;
55
+ }
56
+ export interface CacheManifestEntry {
57
+ ts: string;
58
+ round: number;
59
+ peer: PeerId;
60
+ provider: string;
61
+ model: string;
62
+ cache_key_hash: string;
63
+ cache_provider_mode: "auto" | "explicit" | "implicit" | "not_supported";
64
+ read_tokens?: number;
65
+ write_tokens?: number;
66
+ hit: boolean;
67
+ latency_ms: number;
68
+ estimated_savings_usd?: number;
69
+ savings_unknown?: boolean;
70
+ }
71
+ export interface CacheManifest {
72
+ session_id: string;
73
+ cache_schema_version: string;
74
+ created_at: string;
75
+ updated_at: string;
76
+ entries: CacheManifestEntry[];
77
+ }
78
+ export interface PeerStructuredStatus {
79
+ status: ReviewStatus;
80
+ summary?: string;
81
+ confidence?: Confidence;
82
+ evidence_sources?: string[];
83
+ caller_requests?: string[];
84
+ follow_ups?: string[];
85
+ }
86
+ export interface PeerResult {
87
+ peer: PeerId;
88
+ provider: string;
89
+ model: string;
90
+ model_reported?: string;
91
+ model_match?: boolean;
92
+ status: ReviewStatus | null;
93
+ structured: PeerStructuredStatus | null;
94
+ text: string;
95
+ raw: unknown;
96
+ usage?: TokenUsage;
97
+ cost?: CostEstimate;
98
+ latency_ms: number;
99
+ attempts: number;
100
+ parser_warnings: string[];
101
+ decision_quality: DecisionQuality;
102
+ fallback?: FallbackEvent;
103
+ }
104
+ export interface GenerationResult {
105
+ peer: PeerId;
106
+ provider: string;
107
+ model: string;
108
+ model_reported?: string;
109
+ model_match?: boolean;
110
+ text: string;
111
+ raw: unknown;
112
+ usage?: TokenUsage;
113
+ cost?: CostEstimate;
114
+ latency_ms: number;
115
+ attempts: number;
116
+ fallback?: FallbackEvent;
117
+ parser_warnings?: string[];
118
+ }
119
+ export interface FallbackEvent {
120
+ peer: PeerId;
121
+ provider: string;
122
+ from_model: string;
123
+ to_model: string;
124
+ reason: string;
125
+ ts: string;
126
+ }
127
+ export interface PeerFailure {
128
+ peer: PeerId;
129
+ provider: string;
130
+ model?: string;
131
+ failure_class: "auth" | "rate_limit" | "prompt_flagged_by_moderation" | "silent_model_downgrade" | "provider_error" | "network" | "timeout" | "schema" | "unparseable_after_recovery" | "budget_exceeded" | "budget_preflight" | "cancelled" | "fallback_exhausted" | "format_recovery_exhausted" | "stream_buffer_overflow" | "unknown";
132
+ message: string;
133
+ retryable: boolean;
134
+ recovery_hint?: "wait_and_retry" | "reformulate_and_retry" | "consult_docs_then_revise";
135
+ reformulation_advice?: string;
136
+ retry_after_ms?: number;
137
+ attempts: number;
138
+ latency_ms: number;
139
+ docs_hint?: {
140
+ parameter: string;
141
+ docs_url?: string;
142
+ };
143
+ }
144
+ export interface InFlightRound {
145
+ round: number;
146
+ peers: PeerId[];
147
+ started_at: string;
148
+ status: "running";
149
+ }
150
+ export interface ConvergenceScope {
151
+ petitioner?: PeerId | "operator";
152
+ caller: PeerId | "operator";
153
+ acting_peer?: PeerId | "operator";
154
+ caller_status: ReviewStatus;
155
+ expected_peers: PeerId[];
156
+ reviewer_peers: PeerId[];
157
+ lead_peer?: PeerId;
158
+ lead_peer_role?: "relator_non_voting";
159
+ voting_peers?: PeerId[];
160
+ quorum_basis?: "all_non_lead_panel_peers_ready" | "all_panel_peers_ready";
161
+ anti_self_review_exclusion_reason?: "lead_peer_authored_or_revised_artifact_under_review";
162
+ skipped_peers?: PeerId[];
163
+ }
164
+ export interface ConvergenceHealth {
165
+ state: "idle" | "running" | "converged" | "blocked" | "stale";
166
+ last_event_at: string;
167
+ detail: string;
168
+ idle_ms?: number;
169
+ }
170
+ export interface EvidenceAttachment {
171
+ ts: string;
172
+ label: string;
173
+ path: string;
174
+ content_type?: string;
175
+ }
176
+ export type EvidenceChecklistStatus = "open" | "addressed" | "not_resurfaced" | "satisfied" | "deferred" | "rejected";
177
+ export interface EvidenceChecklistItem {
178
+ id: string;
179
+ peer: PeerId;
180
+ first_round: number;
181
+ last_round: number;
182
+ round_count: number;
183
+ ask: string;
184
+ first_seen_at: string;
185
+ last_seen_at: string;
186
+ status?: EvidenceChecklistStatus;
187
+ addressed_at_round?: number;
188
+ address_method?: "resurfacing" | "judge";
189
+ judge_rationale?: string;
190
+ }
191
+ export interface EvidenceStatusHistoryEntry {
192
+ ts: string;
193
+ item_id: string;
194
+ from: EvidenceChecklistStatus;
195
+ to: EvidenceChecklistStatus;
196
+ by: "runtime" | "operator";
197
+ round?: number;
198
+ note?: string;
199
+ }
200
+ export interface GenerationArtifact {
201
+ ts: string;
202
+ round: number;
203
+ label: string;
204
+ peer: PeerId;
205
+ path: string;
206
+ usage?: TokenUsage;
207
+ cost?: CostEstimate;
208
+ latency_ms?: number;
209
+ }
210
+ export interface OperatorEscalation {
211
+ ts: string;
212
+ reason: string;
213
+ severity: "info" | "warning" | "critical";
214
+ }
215
+ export interface SessionControl {
216
+ status: SessionControlStatus;
217
+ reason?: string;
218
+ job_id?: string;
219
+ requested_at?: string;
220
+ updated_at: string;
221
+ }
222
+ export interface RuntimeCapabilities {
223
+ stable_release: boolean;
224
+ api_only: boolean;
225
+ cli_execution: false;
226
+ durable_sessions: true;
227
+ async_jobs: true;
228
+ cancellation: true;
229
+ restart_recovery: true;
230
+ event_streaming: true;
231
+ token_streaming: boolean;
232
+ budget_preflight: true;
233
+ model_fallback: boolean;
234
+ metrics: true;
235
+ }
236
+ export interface PeerAdapter {
237
+ id: PeerId;
238
+ provider: string;
239
+ model: string;
240
+ call(prompt: string, context: PeerCallContext): Promise<PeerResult>;
241
+ generate(prompt: string, context: PeerCallContext): Promise<GenerationResult>;
242
+ judgeEvidenceAsk(ask: string, draft: string, context: PeerCallContext): Promise<EvidenceAskJudgment>;
243
+ probe(): Promise<PeerProbeResult>;
244
+ }
245
+ export interface EvidenceAskJudgment {
246
+ peer: PeerId;
247
+ provider: string;
248
+ model: string;
249
+ satisfied: boolean;
250
+ confidence: Confidence;
251
+ rationale: string;
252
+ raw: unknown;
253
+ usage?: TokenUsage;
254
+ cost?: CostEstimate;
255
+ latency_ms: number;
256
+ attempts: number;
257
+ parser_warnings: string[];
258
+ }
259
+ export interface PeerCallContext {
260
+ session_id: string;
261
+ round: number;
262
+ task: string;
263
+ signal?: AbortSignal;
264
+ stream?: boolean;
265
+ stream_tokens?: boolean;
266
+ emit(event: RuntimeEvent): void;
267
+ reasoning_effort_override?: ReasoningEffort;
268
+ caller?: PeerId | "operator";
269
+ }
270
+ export interface PeerProbeResult {
271
+ peer: PeerId;
272
+ provider: string;
273
+ model: string;
274
+ available: boolean;
275
+ auth_present: boolean;
276
+ latency_ms: number;
277
+ model_selection?: ModelSelection;
278
+ message?: string;
279
+ }
280
+ export interface RuntimeEvent {
281
+ seq?: number;
282
+ type: string;
283
+ ts?: string;
284
+ session_id?: string;
285
+ round?: number;
286
+ peer?: PeerId;
287
+ message?: string;
288
+ data?: Record<string, unknown>;
289
+ }
290
+ export interface SessionEvent extends RuntimeEvent {
291
+ seq: number;
292
+ }
293
+ export interface SessionMeta {
294
+ session_id: string;
295
+ version: string;
296
+ created_at: string;
297
+ updated_at: string;
298
+ task: string;
299
+ review_focus?: string;
300
+ caller: PeerId | "operator";
301
+ outcome?: SessionOutcome;
302
+ outcome_reason?: string;
303
+ capability_snapshot: PeerProbeResult[];
304
+ in_flight?: InFlightRound;
305
+ convergence_scope?: ConvergenceScope;
306
+ convergence_health?: ConvergenceHealth;
307
+ failed_attempts?: Array<PeerFailure & {
308
+ round: number;
309
+ }>;
310
+ evidence_files?: EvidenceAttachment[];
311
+ evidence_checklist?: EvidenceChecklistItem[];
312
+ evidence_status_history?: EvidenceStatusHistoryEntry[];
313
+ generation_files?: GenerationArtifact[];
314
+ operator_escalations?: OperatorEscalation[];
315
+ control?: SessionControl;
316
+ fallback_events?: FallbackEvent[];
317
+ rounds: ReviewRound[];
318
+ totals: {
319
+ usage: TokenUsage;
320
+ cost: CostEstimate;
321
+ };
322
+ contestation?: {
323
+ contested_at: string;
324
+ reason: string;
325
+ original_outcome: SessionOutcome | null;
326
+ new_session_id: string;
327
+ };
328
+ contests_session_id?: string;
329
+ circular_state?: {
330
+ rotation_order: PeerId[];
331
+ consecutive_no_change_count: number;
332
+ last_revision_round: number | null;
333
+ };
334
+ cost_ceiling_usd?: number | null;
335
+ costs_per_round?: number[];
336
+ budget_warning_emitted?: boolean;
337
+ requested_max_cost_usd?: number | null;
338
+ effective_cost_ceiling_usd?: number | null;
339
+ cost_ceiling_source?: "call_arg" | "env_default" | "config_default";
340
+ requested_max_rounds?: number | null;
341
+ effective_max_rounds?: number | null;
342
+ }
343
+ export interface ReviewRound {
344
+ round: number;
345
+ started_at: string;
346
+ completed_at?: string;
347
+ caller_status: ReviewStatus;
348
+ draft_file?: string;
349
+ prompt_file: string;
350
+ peers: PeerResult[];
351
+ rejected: PeerFailure[];
352
+ convergence: ConvergenceResult;
353
+ }
354
+ export interface ConvergenceResult {
355
+ converged: boolean;
356
+ reason: string;
357
+ latest_round_converged?: boolean;
358
+ session_quorum_converged?: boolean;
359
+ recovery_converged?: boolean;
360
+ quorum_peers?: PeerId[];
361
+ ready_peers: PeerId[];
362
+ not_ready_peers: PeerId[];
363
+ needs_evidence_peers: PeerId[];
364
+ rejected_peers: PeerId[];
365
+ skipped_peers: PeerId[];
366
+ decision_quality: Record<PeerId, DecisionQuality>;
367
+ blocking_details: string[];
368
+ }
369
+ export interface AppConfig {
370
+ version: string;
371
+ data_dir: string;
372
+ log_level: string;
373
+ stub: boolean;
374
+ dashboard_port: number;
375
+ retry: {
376
+ max_attempts: number;
377
+ base_delay_ms: number;
378
+ max_delay_ms: number;
379
+ timeout_ms: number;
380
+ };
381
+ budget: {
382
+ max_session_cost_usd?: number;
383
+ until_stopped_max_cost_usd?: number;
384
+ preflight_max_round_cost_usd?: number;
385
+ require_rates_for_budget: boolean;
386
+ default_max_rounds: number;
387
+ circular_max_rotations: number;
388
+ };
389
+ prompt: {
390
+ max_task_chars: number;
391
+ max_review_focus_chars: number;
392
+ max_history_chars: number;
393
+ max_draft_chars: number;
394
+ max_prior_rounds: number;
395
+ max_peer_requests: number;
396
+ max_attached_evidence_chars: number;
397
+ };
398
+ max_output_tokens: number;
399
+ evidence_preflight_enabled: boolean;
400
+ streaming: {
401
+ events: boolean;
402
+ tokens: boolean;
403
+ include_text: boolean;
404
+ };
405
+ models: Record<PeerId, string>;
406
+ fallback_models: Partial<Record<PeerId, string[]>>;
407
+ reasoning_effort: Partial<Record<PeerId, ReasoningEffort>>;
408
+ model_selection: Partial<Record<PeerId, ModelSelection>>;
409
+ api_keys: Record<PeerId, string | undefined>;
410
+ cost_rates: Partial<Record<PeerId, {
411
+ input_per_million: number;
412
+ output_per_million: number;
413
+ input_extended_per_million?: number;
414
+ output_extended_per_million?: number;
415
+ cache_read_per_million?: number;
416
+ cache_write_per_million?: number;
417
+ cache_read_extended_per_million?: number;
418
+ cache_write_extended_per_million?: number;
419
+ promo_input_per_million?: number;
420
+ promo_output_per_million?: number;
421
+ promo_input_extended_per_million?: number;
422
+ promo_output_extended_per_million?: number;
423
+ promo_cache_read_per_million?: number;
424
+ promo_cache_write_per_million?: number;
425
+ promo_cache_read_extended_per_million?: number;
426
+ promo_cache_write_extended_per_million?: number;
427
+ promo_expires_at?: string;
428
+ threshold_tokens?: number;
429
+ request_fee_low_per_1000?: number;
430
+ request_fee_medium_per_1000?: number;
431
+ request_fee_high_per_1000?: number;
432
+ citation_tokens_per_million?: number;
433
+ deep_research_reasoning_tokens_per_million?: number;
434
+ search_queries_per_1000?: number;
435
+ }>>;
436
+ evidence_judge_autowire: EvidenceJudgeAutowireConfig;
437
+ peer_enabled: Record<PeerId, boolean>;
438
+ cache: {
439
+ schema_version: string;
440
+ enabled: boolean;
441
+ ttl: {
442
+ anthropic: "5m" | "1h";
443
+ openai: "5m" | "1h";
444
+ };
445
+ disable_per_peer: Record<PeerId, boolean>;
446
+ };
447
+ perplexity: {
448
+ search_context_size: "low" | "medium" | "high";
449
+ disable_search: boolean;
450
+ };
451
+ }
452
+ export type EvidenceJudgeAutowireMode = "off" | "shadow" | "active";
453
+ export interface EvidenceJudgeAutowireConfig {
454
+ mode: EvidenceJudgeAutowireMode | string;
455
+ peer: PeerId | undefined;
456
+ active: boolean;
457
+ max_items_per_pass: number;
458
+ configured_mode_raw: string;
459
+ configured_peer_raw: string;
460
+ consensus_peers: PeerId[];
461
+ configured_consensus_peers_raw: string;
462
+ }
463
+ export interface PeerHealthSummary {
464
+ peer: PeerId;
465
+ results_total: number;
466
+ ready_count: number;
467
+ not_ready_count: number;
468
+ needs_evidence_count: number;
469
+ unresolved_count: number;
470
+ ready_rate: number;
471
+ needs_evidence_rate: number;
472
+ avg_cost_usd: number | null;
473
+ total_cost_usd: number | null;
474
+ parser_warnings_total: number;
475
+ rejected_total: number;
476
+ failures_by_class: Partial<Record<PeerFailure["failure_class"], number>>;
477
+ }
478
+ export interface ShadowJudgmentRollup {
479
+ decisions_total: number;
480
+ would_promote_total: number;
481
+ by_judge_peer: Partial<Record<PeerId, ShadowJudgmentPeerStats>>;
482
+ }
483
+ export interface JudgmentPrecisionPeerStats {
484
+ judge_peer: PeerId;
485
+ decisions_total: number;
486
+ decisions_with_ground_truth: number;
487
+ decisions_skipped_no_ground_truth: number;
488
+ true_positive: number;
489
+ false_positive: number;
490
+ true_negative: number;
491
+ false_negative: number;
492
+ precision: number | null;
493
+ recall: number | null;
494
+ f1: number | null;
495
+ by_confidence: Partial<Record<Confidence, {
496
+ tp: number;
497
+ fp: number;
498
+ tn: number;
499
+ fn: number;
500
+ }>>;
501
+ }
502
+ export interface JudgmentPrecisionReport {
503
+ generated_at: string;
504
+ peer_filter?: PeerId;
505
+ since_filter?: string;
506
+ session_filter?: string;
507
+ decisions_total: number;
508
+ decisions_with_ground_truth: number;
509
+ decisions_skipped_no_ground_truth: number;
510
+ by_judge_peer: Partial<Record<PeerId, JudgmentPrecisionPeerStats>>;
511
+ }
512
+ export interface ShadowJudgmentPeerStats {
513
+ judge_peer: PeerId;
514
+ decisions_total: number;
515
+ would_promote: number;
516
+ would_skip_satisfied_unverified: number;
517
+ would_skip_not_satisfied: number;
518
+ by_confidence: Partial<Record<Confidence, number>>;
519
+ first_seen_at: string | null;
520
+ last_seen_at: string | null;
521
+ }
522
+ export interface RuntimeMetrics {
523
+ generated_at: string;
524
+ scope: "all" | "session";
525
+ session_id?: string;
526
+ sessions: {
527
+ total: number;
528
+ converged: number;
529
+ aborted: number;
530
+ max_rounds: number;
531
+ unfinished: number;
532
+ };
533
+ rounds: number;
534
+ peer_results: Partial<Record<PeerId, number>>;
535
+ peer_failures: Partial<Record<PeerFailure["failure_class"], number>>;
536
+ decision_quality: Partial<Record<DecisionQuality, number>>;
537
+ moderation_recoveries: number;
538
+ fallback_events: number;
539
+ total_usage: TokenUsage;
540
+ total_cost: CostEstimate;
541
+ latency_ms: {
542
+ peer_average: number | null;
543
+ generation_average: number | null;
544
+ };
545
+ per_peer_health: Partial<Record<PeerId, PeerHealthSummary>>;
546
+ shadow_judgment: ShadowJudgmentRollup;
547
+ }
548
+ export interface SessionDoctorEntry {
549
+ session_id: string;
550
+ version?: string;
551
+ caller?: PeerId | "operator";
552
+ petitioner?: PeerId | "operator";
553
+ lead_peer?: PeerId;
554
+ outcome?: SessionOutcome;
555
+ outcome_reason?: string;
556
+ health_state?: ConvergenceHealth["state"];
557
+ health_detail?: string;
558
+ rounds: number;
559
+ updated_at: string;
560
+ open_evidence_items?: number;
561
+ grok_provider_errors?: number;
562
+ event_read_error?: string;
563
+ item_types?: Partial<Record<PeerId, number>>;
564
+ chronic_blockers?: string[];
565
+ }
566
+ export interface SessionDoctorReport {
567
+ generated_at: string;
568
+ scope: "all";
569
+ limit: number;
570
+ totals: {
571
+ sessions: number;
572
+ open: number;
573
+ stale: number;
574
+ blocked: number;
575
+ max_rounds: number;
576
+ self_lead_metadata: number;
577
+ open_evidence_sessions: number;
578
+ grok_provider_error_sessions: number;
579
+ event_read_error_sessions: number;
580
+ };
581
+ findings: {
582
+ open_sessions: SessionDoctorEntry[];
583
+ stale_sessions: SessionDoctorEntry[];
584
+ blocked_sessions: SessionDoctorEntry[];
585
+ max_rounds_sessions: SessionDoctorEntry[];
586
+ self_lead_metadata: SessionDoctorEntry[];
587
+ open_evidence_sessions: SessionDoctorEntry[];
588
+ grok_provider_error_sessions: SessionDoctorEntry[];
589
+ event_read_error_sessions: SessionDoctorEntry[];
590
+ };
591
+ event_noise: {
592
+ events_total: number;
593
+ token_delta_events: number;
594
+ token_completed_events: number;
595
+ token_delta_ratio: number | null;
596
+ };
597
+ recommendations: string[];
598
+ repaired?: Array<{
599
+ session_id: string;
600
+ from_health_state: ConvergenceHealth["state"] | undefined;
601
+ to_health_state: ConvergenceHealth["state"];
602
+ reason: string;
603
+ }>;
604
+ }
@@ -0,0 +1,36 @@
1
+ // v2.14.0 (item 5, operator directive 2026-05-04): Grok joined the
2
+ // quarteto, making it a quinteto. Per `project_cross_review_v2_grok_integration_pending.md`,
3
+ // xAI's Grok uses the OpenAI Responses API surface at base URL
4
+ // `https://api.x.ai/v1`. Auth is via GROK_API_KEY. Operators may choose
5
+ // `grok-4-latest` / `grok-4.3` (xAI automatic reasoning, no
6
+ // reasoning.effort body field) or `grok-4.20-multi-agent` (explicit
7
+ // reasoning.effort supported).
8
+ // Adapter at `peers/grok.ts` inherits the same Responses API code path
9
+ // the OpenAI adapter uses.
10
+ //
11
+ // v3.0.0 (operator directive 2026-05-12): Perplexity joined the
12
+ // quinteto, making it a sexteto. Per
13
+ // `project_cross_review_v2_v300_perplexity_sixth_peer.md`, Perplexity's
14
+ // Sonar API is OpenAI-Chat-Completions-compatible but lives at a
15
+ // distinct endpoint `https://api.perplexity.ai/v1/sonar`. Auth is via
16
+ // PERPLEXITY_API_KEY. Operators may choose `sonar` / `sonar-pro` /
17
+ // `sonar-reasoning-pro` (default; reasoning + grounding) /
18
+ // `sonar-deep-research` (multi-hop research; minutes per call).
19
+ // Distinct architectural traits vs the other 5 peers: (1) EVERY call
20
+ // performs web search by default — peer becomes a real-time fact-check
21
+ // channel; (2) system prompts ONLY shape tone/style of the final
22
+ // answer — the search component does not attend to them; (3) pricing
23
+ // has a third dimension (per-1000-request fee that scales with
24
+ // `search_context_size` low/medium/high) beyond input/output tokens;
25
+ // (4) usage.cost is reported per-call by the API in USD breakdown
26
+ // (a built-in we read directly for FinOps reconciliation, distinct
27
+ // from the config-driven cost layer); (5) `reasoning_effort` enum is
28
+ // `minimal|low|medium|high` only (no `xhigh`/`max`/`none`). All 6
29
+ // peers remain symmetric in role assignment — caller / lead_peer /
30
+ // reviewer — only the workspace HARD GATE rules apply uniformly
31
+ // (caller != lead_peer != reviewer).
32
+ // Adapter at `peers/perplexity.ts` reuses the shared `loadOpenAICtor`
33
+ // helper introduced in v2.27.1.
34
+ export const PEERS = ["codex", "claude", "gemini", "deepseek", "grok", "perplexity"];
35
+ export const STATUSES = ["READY", "NOT_READY", "NEEDS_EVIDENCE"];
36
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/core/types.ts"],"names":[],"mappings":"AAAA,mEAAmE;AACnE,6FAA6F;AAC7F,+DAA+D;AAC/D,wEAAwE;AACxE,4DAA4D;AAC5D,oEAAoE;AACpE,+BAA+B;AAC/B,uEAAuE;AACvE,2BAA2B;AAC3B,EAAE;AACF,gEAAgE;AAChE,qCAAqC;AACrC,wEAAwE;AACxE,iEAAiE;AACjE,sEAAsE;AACtE,mEAAmE;AACnE,2DAA2D;AAC3D,gEAAgE;AAChE,qEAAqE;AACrE,uEAAuE;AACvE,iEAAiE;AACjE,qEAAqE;AACrE,+DAA+D;AAC/D,qEAAqE;AACrE,kEAAkE;AAClE,mEAAmE;AACnE,qEAAqE;AACrE,kEAAkE;AAClE,mEAAmE;AACnE,gEAAgE;AAChE,qCAAqC;AACrC,sEAAsE;AACtE,gCAAgC;AAChC,MAAM,CAAC,MAAM,KAAK,GAAG,CAAC,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,EAAE,YAAY,CAAU,CAAC;AAG9F,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,OAAO,EAAE,WAAW,EAAE,gBAAgB,CAAU,CAAC"}
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};