helixevo 0.7.0 → 0.8.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.
@@ -56,6 +56,12 @@ function toneForChange(changeType: string): 'blue' | 'green' | 'purple' | 'yello
56
56
  return 'neutral'
57
57
  }
58
58
 
59
+ function toneForOptimizeStatus(status: TopologyDashboardSummary['optimizeStatus']['status']): 'green' | 'yellow' | 'neutral' {
60
+ if (status === 'healthy') return 'green'
61
+ if (status === 'partial' || status === 'failed') return 'yellow'
62
+ return 'neutral'
63
+ }
64
+
59
65
  function consoleTone(state: RunState): 'neutral' | 'green' | 'red' | 'yellow' {
60
66
  if (state === 'success') return 'green'
61
67
  if (state === 'error') return 'red'
@@ -247,6 +253,7 @@ export default function TopologyClient({
247
253
  { label: `${dashboard.summary.open} open reviews`, tone: dashboard.summary.open > 0 ? 'yellow' : 'green' },
248
254
  { label: `${dashboard.execution.prepared} prepared`, tone: dashboard.execution.prepared > 0 ? 'blue' : 'neutral' },
249
255
  { label: `${dashboard.execution.applied} applied`, tone: dashboard.execution.applied > 0 ? 'green' : 'neutral' },
256
+ { label: `optimize: ${dashboard.optimizeStatus.status}`, tone: toneForOptimizeStatus(dashboard.optimizeStatus.status) },
250
257
  { label: `${proof.summary.reviewOpen} proof review`, tone: proof.summary.reviewOpen > 0 ? 'yellow' : proof.summary.effective > 0 ? 'green' : 'neutral' },
251
258
  { label: formatMode(dashboard.governance.activeMode), tone: toneForMode(dashboard.governance.activeMode) },
252
259
  { label: dashboard.governance.source === 'operator-selected' ? 'operator-steered' : 'derived mode', tone: dashboard.governance.source === 'operator-selected' ? 'purple' : 'neutral' },
@@ -258,9 +265,15 @@ export default function TopologyClient({
258
265
  <div className="hero-note-title">{formatMode(dashboard.governance.activeMode)}</div>
259
266
  <div className="hero-note-copy">{dashboard.governance.profile.explanation}</div>
260
267
  <div style={{ marginTop: 8, display: 'flex', gap: 6, flexWrap: 'wrap' }}>
268
+ <span className={`badge badge-${dashboard.optimizeStatus.status === 'healthy' ? 'green' : dashboard.optimizeStatus.status === 'idle' ? 'gray' : 'yellow'}`}>optimize {dashboard.optimizeStatus.status}</span>
261
269
  <span className="badge badge-gray">{proof.summary.effective} effective records</span>
262
270
  <Link href="/proof" className="badge badge-gray" style={{ textDecoration: 'none' }}>open proof</Link>
263
271
  </div>
272
+ {dashboard.optimizeStatus.status !== 'idle' ? (
273
+ <div style={{ marginTop: 10, fontSize: 12, color: 'var(--text-dim)', lineHeight: 1.6 }}>
274
+ {dashboard.optimizeStatus.summary}
275
+ </div>
276
+ ) : null}
264
277
  </div>
265
278
  <div style={{ display: 'grid', gap: 10 }}>
266
279
  <div style={{ display: 'flex', gap: 10, flexWrap: 'wrap', justifyContent: 'flex-end' }}>
@@ -284,6 +297,32 @@ export default function TopologyClient({
284
297
  <MetricCard label="Snapshots" value={dashboard.execution.snapshots} sublabel="before/after state preserved for reviewed execution" tone="purple" icon="◎" />
285
298
  </div>
286
299
 
300
+ <SectionFrame
301
+ eyebrow="Latest optimize run"
302
+ title="Full vs partial structural refresh is now explicit"
303
+ description="Queue refresh and conflict enrichment are tracked separately so a degraded optimize run can still expose a real review queue without pretending the full enrichment pass succeeded."
304
+ tone={toneForOptimizeStatus(dashboard.optimizeStatus.status)}
305
+ >
306
+ <div style={{ display: 'grid', gap: 12 }}>
307
+ <div style={{ display: 'flex', gap: 8, flexWrap: 'wrap' }}>
308
+ <span className={`badge badge-${dashboard.optimizeStatus.status === 'healthy' ? 'green' : dashboard.optimizeStatus.status === 'idle' ? 'gray' : 'yellow'}`}>{dashboard.optimizeStatus.status}</span>
309
+ <span className="badge badge-gray">queue {dashboard.optimizeStatus.queue.total} total • {dashboard.optimizeStatus.queue.open} open</span>
310
+ <span className="badge badge-gray">created {dashboard.optimizeStatus.queue.created} • updated {dashboard.optimizeStatus.queue.updated}</span>
311
+ <span className="badge badge-gray">enrichment {dashboard.optimizeStatus.enrichment.resolved} resolved • {dashboard.optimizeStatus.enrichment.failed} failed • {dashboard.optimizeStatus.enrichment.skipped} skipped</span>
312
+ {dashboard.optimizeStatus.ranAt ? <span className="badge badge-gray">ran {formatDate(dashboard.optimizeStatus.ranAt)}</span> : null}
313
+ </div>
314
+ <div className="signal-text">{dashboard.optimizeStatus.summary}</div>
315
+ {dashboard.optimizeStatus.nextStep ? <div className="signal-text">→ {dashboard.optimizeStatus.nextStep}</div> : null}
316
+ {dashboard.optimizeStatus.notices.length > 0 ? (
317
+ <div style={{ display: 'grid', gap: 4 }}>
318
+ {dashboard.optimizeStatus.notices.slice(0, 3).map((notice, index) => (
319
+ <div key={`${dashboard.optimizeStatus.status}-${index}`} className="signal-text">• {notice}</div>
320
+ ))}
321
+ </div>
322
+ ) : null}
323
+ </div>
324
+ </SectionFrame>
325
+
287
326
  <SectionFrame
288
327
  eyebrow="Execution pipeline"
289
328
  title="Accepted review can now become prepared and applied structure"
@@ -512,10 +512,94 @@ export interface CoEvolutionDashboardSummary {
512
512
  recentTopologyDecisions: ResolvedTopologyReviewCandidate[]
513
513
  }
514
514
 
515
+ export type TopologyOptimizeStatusKind = 'idle' | 'healthy' | 'partial' | 'failed'
516
+ export type TopologyOptimizeFailureKind = 'auth' | 'timeout' | 'spawn' | 'llm' | 'unknown'
517
+
518
+ export interface TopologyOptimizeStatus {
519
+ command: 'graph-optimize'
520
+ status: TopologyOptimizeStatusKind
521
+ ranAt?: string
522
+ summary: string
523
+ nextStep?: string
524
+ notices: string[]
525
+ queue: {
526
+ total: number
527
+ open: number
528
+ created: number
529
+ updated: number
530
+ }
531
+ enrichment: {
532
+ attempted: number
533
+ resolved: number
534
+ failed: number
535
+ skipped: number
536
+ degraded: boolean
537
+ failureKind?: TopologyOptimizeFailureKind
538
+ warning?: string
539
+ }
540
+ }
541
+
542
+ export type LLMProviderId = 'claude-code' | 'codex' | 'ollama'
543
+ export type LLMFallbackPolicy = 'disabled' | 'on-failure'
544
+ export type LLMProviderHealthStatus = 'healthy' | 'degraded' | 'unavailable' | 'unknown'
545
+ export type LLMProviderFailureKind = 'auth' | 'timeout' | 'spawn' | 'network' | 'not-installed' | 'not-configured' | 'model-missing' | 'unknown'
546
+ export type LLMCapability = 'chat' | 'json' | 'judge' | 'web-search'
547
+
548
+ export interface LLMProviderSnapshot {
549
+ provider: LLMProviderId
550
+ configured: boolean
551
+ enabled: boolean
552
+ installed: boolean
553
+ available: boolean
554
+ loggedIn?: boolean
555
+ authMethod?: string
556
+ apiProvider?: string
557
+ status: LLMProviderHealthStatus
558
+ model?: string
559
+ judgeModel?: string
560
+ summary: string
561
+ nextStep?: string
562
+ failureKind?: LLMProviderFailureKind
563
+ warning?: string
564
+ notices: string[]
565
+ lastCheckedAt?: string
566
+ lastSelectedAt?: string
567
+ lastUsedAt?: string
568
+ lastSucceededAt?: string
569
+ lastFailedAt?: string
570
+ lastFailureMessage?: string
571
+ }
572
+
573
+ export interface LLMExecutionRecord {
574
+ capability: LLMCapability
575
+ scope: 'shared' | 'claude-only'
576
+ selectionMode: 'default' | 'explicit'
577
+ selectedProvider: LLMProviderId
578
+ attemptedProviders: LLMProviderId[]
579
+ usedProvider?: LLMProviderId
580
+ fallbackUsed: boolean
581
+ success: boolean
582
+ ranAt: string
583
+ summary: string
584
+ nextStep?: string
585
+ failureKind?: LLMProviderFailureKind
586
+ warning?: string
587
+ }
588
+
589
+ export interface LLMRuntimeState {
590
+ updatedAt: string
591
+ defaultProvider: LLMProviderId
592
+ fallbackPolicy: LLMFallbackPolicy
593
+ fallbackOrder: LLMProviderId[]
594
+ lastExecution?: LLMExecutionRecord
595
+ providers: Record<LLMProviderId, LLMProviderSnapshot>
596
+ }
597
+
515
598
  export interface TopologyDashboardSummary {
516
599
  governance: ActiveGovernanceSummary
517
600
  summary: CoEvolutionDashboardSummary['topologyReviews']
518
601
  execution: CoEvolutionDashboardSummary['topologyExecution']
602
+ optimizeStatus: TopologyOptimizeStatus
519
603
  backlog: ResolvedTopologyReviewCandidate[]
520
604
  recentDecisions: ResolvedTopologyReviewCandidate[]
521
605
  acceptedReady: ResolvedTopologyReviewCandidate[]
@@ -1407,15 +1491,108 @@ export function getTopologyReviewSummary() {
1407
1491
  }
1408
1492
  }
1409
1493
 
1494
+ const DEFAULT_TOPOLOGY_OPTIMIZE_STATUS: TopologyOptimizeStatus = {
1495
+ command: 'graph-optimize',
1496
+ status: 'idle',
1497
+ summary: 'No optimize run recorded yet.',
1498
+ notices: [],
1499
+ queue: {
1500
+ total: 0,
1501
+ open: 0,
1502
+ created: 0,
1503
+ updated: 0,
1504
+ },
1505
+ enrichment: {
1506
+ attempted: 0,
1507
+ resolved: 0,
1508
+ failed: 0,
1509
+ skipped: 0,
1510
+ degraded: false,
1511
+ },
1512
+ }
1513
+
1514
+ export function loadTopologyOptimizeStatus(): TopologyOptimizeStatus {
1515
+ return readJson<TopologyOptimizeStatus>('topology-optimize-status.json', DEFAULT_TOPOLOGY_OPTIMIZE_STATUS)
1516
+ }
1517
+
1518
+ const DEFAULT_LLM_RUNTIME_STATE: LLMRuntimeState = {
1519
+ updatedAt: new Date(0).toISOString(),
1520
+ defaultProvider: 'claude-code',
1521
+ fallbackPolicy: 'disabled',
1522
+ fallbackOrder: [],
1523
+ providers: {
1524
+ 'claude-code': {
1525
+ provider: 'claude-code',
1526
+ configured: true,
1527
+ enabled: true,
1528
+ installed: false,
1529
+ available: false,
1530
+ status: 'unknown',
1531
+ model: 'sonnet',
1532
+ judgeModel: 'sonnet',
1533
+ summary: 'No Claude provider health has been recorded yet.',
1534
+ notices: [],
1535
+ },
1536
+ codex: {
1537
+ provider: 'codex',
1538
+ configured: false,
1539
+ enabled: false,
1540
+ installed: false,
1541
+ available: false,
1542
+ status: 'unknown',
1543
+ model: 'gpt-5-codex',
1544
+ judgeModel: 'gpt-5-codex',
1545
+ summary: 'No Codex provider health has been recorded yet.',
1546
+ notices: [],
1547
+ },
1548
+ ollama: {
1549
+ provider: 'ollama',
1550
+ configured: false,
1551
+ enabled: false,
1552
+ installed: false,
1553
+ available: false,
1554
+ status: 'unknown',
1555
+ model: 'qwen3-coder:latest',
1556
+ judgeModel: 'qwen3-coder:latest',
1557
+ summary: 'No Ollama provider health has been recorded yet.',
1558
+ notices: [],
1559
+ },
1560
+ },
1561
+ }
1562
+
1563
+ export function loadLlmRuntimeState(): LLMRuntimeState {
1564
+ const state = readJson<LLMRuntimeState>('llm-runtime-state.json', DEFAULT_LLM_RUNTIME_STATE)
1565
+ return {
1566
+ ...DEFAULT_LLM_RUNTIME_STATE,
1567
+ ...state,
1568
+ providers: {
1569
+ 'claude-code': {
1570
+ ...DEFAULT_LLM_RUNTIME_STATE.providers['claude-code'],
1571
+ ...(state.providers?.['claude-code'] ?? {}),
1572
+ },
1573
+ codex: {
1574
+ ...DEFAULT_LLM_RUNTIME_STATE.providers.codex,
1575
+ ...(state.providers?.codex ?? {}),
1576
+ },
1577
+ ollama: {
1578
+ ...DEFAULT_LLM_RUNTIME_STATE.providers.ollama,
1579
+ ...(state.providers?.ollama ?? {}),
1580
+ },
1581
+ },
1582
+ }
1583
+ }
1584
+
1410
1585
  export function loadTopologyDashboardSummary(): TopologyDashboardSummary {
1411
1586
  const governance = getActiveGovernanceSummary()
1412
1587
  const summary = getTopologyReviewSummary()
1413
1588
  const execution = getTopologyExecutionSummary()
1589
+ const optimizeStatus = loadTopologyOptimizeStatus()
1414
1590
  const candidates = loadResolvedTopologyReviewCandidates()
1415
1591
  return {
1416
1592
  governance,
1417
1593
  summary,
1418
1594
  execution,
1595
+ optimizeStatus,
1419
1596
  backlog: summary.backlog,
1420
1597
  recentDecisions: summary.recentDecisions,
1421
1598
  acceptedReady: execution.acceptedReady,
@@ -1,17 +1,17 @@
1
1
  export const CURRENT_RELEASE_SPOTLIGHT = {
2
- version: '0.7.0',
3
- title: 'What changed in 0.7.0',
2
+ version: '0.8.0',
3
+ title: 'What changed in 0.8.0',
4
4
  summary:
5
- 'This release turns Prove into a first-class operator stage: HelixEvo now unifies bounded outcome attribution across interventions, semantic adoption, topology execution, transfer, and legacy evolution impact.',
5
+ 'This grouped release hardens HelixEvo’s actuation layer and makes provider control explicit: optimize/reporting is more truthful under degraded conditions, Claude Code stays the default provider, and Codex plus Ollama become optional backends for supported shared paths.',
6
6
  bullets: [
7
- 'HelixEvo now ships a dedicated Proof route and proof review API instead of treating metrics alone as the full prove surface.',
8
- 'Overview, Co-Evolution, Ontology, and Topology now expose proof visibility and direct handoffs into bounded outcome review.',
9
- 'The operator loop now lands Prove on /proof, keeping navigation, handoffs, Commands, and Guide aligned with the shipped product.',
10
- 'Proof remains deliberately bounded: measuring, mixed, regressed, and insufficient-evidence states stay visible instead of being overclaimed as certainty.',
7
+ 'HelixEvo now preserves useful topology review refreshes even when conflict enrichment degrades, and it records the difference explicitly instead of hiding it behind brittle failure.',
8
+ 'Provider control is now first-class: status and Overview show default provider, degraded state, last execution truth, and fallback usage instead of treating backend execution as a hidden monolith.',
9
+ 'Claude Code remains the default provider, while GPT Codex and Ollama are available as optional providers for shared prompt-in / text-out operations.',
10
+ 'Claude-backed web search and research remain explicitly Claude-scoped, preserving capability truth instead of pretending full provider symmetry where it does not exist yet.',
11
11
  ],
12
12
  nextActions: [
13
- { label: 'Open proof control', href: '/proof', tone: 'blue' as const },
14
- { label: 'Inspect co-evolution', href: '/coevolution', tone: 'purple' as const },
15
- { label: 'Read proof + metrics', href: '/guide#metrics', tone: 'green' as const },
13
+ { label: 'Inspect backend truth', href: '/commands', tone: 'blue' as const },
14
+ { label: 'Review topology state', href: '/topology', tone: 'purple' as const },
15
+ { label: 'Read provider guide', href: '/guide#config', tone: 'green' as const },
16
16
  ],
17
17
  } as const