helixevo 0.7.0 → 0.8.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.
@@ -1,13 +1,11 @@
1
1
  import Link from 'next/link'
2
- import { getDashboardSummary, getOntologyDashboardSummary, loadCoEvolutionSummary, loadFailures, loadFrontier, loadGraph, loadHistory, listProjects } from '@/lib/data'
2
+ import { getDashboardSummary, getOntologyDashboardSummary, loadCoEvolutionSummary, loadFailures, loadFrontier, loadGraph, loadHistory, listProjects, loadTopologyDashboardSummary, loadLlmRuntimeState } from '@/lib/data'
3
3
  import { loadProofDashboardSummary } from '@/lib/proof'
4
4
  import { OverviewActions } from '@/components/overview-actions'
5
5
  import { PageHero } from '@/components/page-hero'
6
6
  import { MetricCard } from '@/components/metric-card'
7
7
  import { SectionFrame } from '@/components/section-frame'
8
8
  import { OperatorLoopTrail } from '@/components/operator-loop-trail'
9
- import { SurfaceJumpLinks } from '@/components/surface-jump-links'
10
- import { CURRENT_RELEASE_SPOTLIGHT } from '@/lib/release-spotlight'
11
9
 
12
10
  export const dynamic = 'force-dynamic'
13
11
 
@@ -17,10 +15,94 @@ function scoreColor(score: number) {
17
15
  return 'var(--red)'
18
16
  }
19
17
 
18
+ function providerLabel(provider: 'claude-code' | 'codex' | 'ollama') {
19
+ if (provider === 'claude-code') return 'Claude Code'
20
+ if (provider === 'codex') return 'GPT Codex'
21
+ return 'Ollama'
22
+ }
23
+
24
+ function providerTone(status: 'healthy' | 'degraded' | 'unavailable' | 'unknown') {
25
+ if (status === 'healthy') return 'green' as const
26
+ if (status === 'degraded') return 'yellow' as const
27
+ if (status === 'unavailable') return 'red' as const
28
+ return 'neutral' as const
29
+ }
30
+
31
+ function getPriorityActions(params: {
32
+ unresolved: number
33
+ proofOpen: number
34
+ topologyOpen: number
35
+ optimizeStatus: 'idle' | 'healthy' | 'partial' | 'failed'
36
+ optimizeNextStep?: string
37
+ providerStatus: 'healthy' | 'degraded' | 'unavailable' | 'unknown'
38
+ providerSummary: string
39
+ providerNextStep?: string
40
+ }) {
41
+ const actions: Array<{ href: string; title: string; description: string; tone: 'blue' | 'green' | 'purple' | 'yellow' }> = []
42
+
43
+ if (params.providerStatus === 'degraded' || params.providerStatus === 'unavailable') {
44
+ actions.push({
45
+ href: '/commands',
46
+ title: 'Stabilize provider control',
47
+ description: params.providerNextStep ?? params.providerSummary,
48
+ tone: 'yellow',
49
+ })
50
+ }
51
+
52
+ if (params.optimizeStatus === 'partial' || params.optimizeStatus === 'failed') {
53
+ actions.push({
54
+ href: '/topology',
55
+ title: 'Review degraded optimize state',
56
+ description: params.optimizeNextStep ?? 'The review queue refreshed, but structural enrichment did not complete fully. Inspect topology control before treating the queue as fully enriched.',
57
+ tone: 'yellow',
58
+ })
59
+ }
60
+
61
+ if (params.proofOpen > 0) {
62
+ actions.push({
63
+ href: '/proof',
64
+ title: 'Review open proof records',
65
+ description: `${params.proofOpen} proof record${params.proofOpen === 1 ? '' : 's'} currently need operator review before the prove layer becomes more trustworthy.`,
66
+ tone: 'blue',
67
+ })
68
+ }
69
+
70
+ if (params.topologyOpen > 0) {
71
+ actions.push({
72
+ href: '/topology',
73
+ title: 'Triage structural backlog',
74
+ description: `${params.topologyOpen} topology review item${params.topologyOpen === 1 ? '' : 's'} are waiting for accept/defer/reject decisions.`,
75
+ tone: 'purple',
76
+ })
77
+ }
78
+
79
+ if (params.unresolved > 0) {
80
+ actions.push({
81
+ href: '/coevolution',
82
+ title: 'Route live pressure',
83
+ description: `${params.unresolved} unresolved correction${params.unresolved === 1 ? '' : 's'} still need to be routed back into the learning loop.`,
84
+ tone: 'green',
85
+ })
86
+ }
87
+
88
+ if (actions.length === 0) {
89
+ actions.push({
90
+ href: '/projects',
91
+ title: 'Setup a project',
92
+ description: 'Analyze a folder or GitHub repo, match skills, and identify capability gaps to seed the next loop.',
93
+ tone: 'green',
94
+ })
95
+ }
96
+
97
+ return actions.slice(0, 3)
98
+ }
99
+
20
100
  export default function Overview() {
21
101
  const summary = getDashboardSummary()
22
102
  const ontology = getOntologyDashboardSummary()
23
103
  const coevolution = loadCoEvolutionSummary()
104
+ const topologyControl = loadTopologyDashboardSummary()
105
+ const llmRuntime = loadLlmRuntimeState()
24
106
  const proof = loadProofDashboardSummary()
25
107
  const frontier = loadFrontier()
26
108
  const history = loadHistory()
@@ -29,6 +111,37 @@ export default function Overview() {
29
111
  const unresolved = failures.filter((failure) => !failure.resolved)
30
112
  const recentRuns = history.iterations.slice(-4).reverse()
31
113
  const topSkills = [...graph.nodes].sort((a, b) => b.score - a.score).slice(0, 10)
114
+ const defaultProvider = llmRuntime.providers[llmRuntime.defaultProvider]
115
+ const lastExecutionUsedFallback = Boolean(llmRuntime.lastExecution?.fallbackUsed)
116
+ const isProviderDegraded =
117
+ defaultProvider.status === 'degraded' ||
118
+ defaultProvider.status === 'unavailable'
119
+ const showProviderAttention = isProviderDegraded || lastExecutionUsedFallback
120
+ const providerAttentionTone = defaultProvider.status === 'unavailable' ? 'red' : 'yellow'
121
+ const providerAttentionEyebrow = isProviderDegraded ? 'Provider attention' : 'Recent provider deviation'
122
+ const providerAttentionTitle = defaultProvider.status === 'unavailable'
123
+ ? 'Backend recovery needed'
124
+ : isProviderDegraded
125
+ ? 'Live backend truth'
126
+ : 'Fallback used recently'
127
+ const providerAttentionDescription = isProviderDegraded
128
+ ? lastExecutionUsedFallback
129
+ ? 'The default provider currently needs attention and a recent provider-backed run used explicit fallback. Review runtime health before treating execution as fully healthy or default-aligned.'
130
+ : 'The default provider currently needs attention. Review runtime health before treating provider-backed execution as fully healthy.'
131
+ : llmRuntime.lastExecution?.usedProvider
132
+ ? `A recent provider-backed run did not stay on the selected default provider. The default remained ${providerLabel(llmRuntime.defaultProvider)}, but the last successful execution used ${providerLabel(llmRuntime.lastExecution.usedProvider)}. Review provider health and fallback policy before assuming default-provider execution.`
133
+ : 'A recent provider-backed run used explicit fallback instead of staying on the selected default provider. Review provider health and fallback policy before assuming default-provider execution.'
134
+ const priorityActions = getPriorityActions({
135
+ unresolved: summary.failures.unresolved,
136
+ proofOpen: proof.summary.reviewOpen,
137
+ topologyOpen: topologyControl.summary.open,
138
+ optimizeStatus: topologyControl.optimizeStatus.status,
139
+ optimizeNextStep: topologyControl.optimizeStatus.nextStep,
140
+ providerStatus: defaultProvider.status,
141
+ providerSummary: defaultProvider.summary,
142
+ providerNextStep: defaultProvider.nextStep,
143
+ })
144
+ const primaryAction = priorityActions[0]
32
145
 
33
146
  return (
34
147
  <div className="overview-grid">
@@ -37,27 +150,23 @@ export default function Overview() {
37
150
  title="Dashboard"
38
151
  description="Monitor the live state of your self-evolving skill ecosystem, launch high-value actions, and trace how failures turn into frontier-worthy improvements."
39
152
  chips={[
40
- { label: `${summary.skills.total} skills`, tone: 'purple' },
41
153
  { label: `${summary.failures.unresolved} unresolved corrections`, tone: summary.failures.unresolved > 0 ? 'yellow' : 'green' },
42
- { label: `${summary.evolution.runs} evolution runs`, tone: 'blue' },
43
- { label: `${frontier.programs.length}/${frontier.capacity} frontier slots`, tone: 'green' },
44
- { label: `${coevolution.pressureMotifs.promotionReady} promotion-ready motifs`, tone: coevolution.pressureMotifs.promotionReady > 0 ? 'purple' : 'neutral' },
45
- { label: `${coevolution.topologyReviews.open} topology reviews`, tone: coevolution.topologyReviews.open > 0 ? 'yellow' : 'green' },
46
- { label: `${coevolution.topologyExecution.prepared} prepared structural plans`, tone: coevolution.topologyExecution.prepared > 0 ? 'blue' : 'neutral' },
47
154
  { label: `${proof.summary.reviewOpen} proof reviews`, tone: proof.summary.reviewOpen > 0 ? 'yellow' : proof.summary.effective > 0 ? 'green' : 'neutral' },
155
+ { label: `${coevolution.topologyReviews.open} topology reviews`, tone: coevolution.topologyReviews.open > 0 ? 'yellow' : 'green' },
156
+ { label: `${providerLabel(llmRuntime.defaultProvider)} ${defaultProvider.status}`, tone: providerTone(defaultProvider.status) },
48
157
  { label: `mode: ${coevolution.governance.activeMode.replace(/-/g, ' ')}`, tone: coevolution.governance.activeMode === 'transfer-focused' ? 'purple' : coevolution.governance.activeMode === 'project-critical' ? 'yellow' : 'blue' },
49
158
  ]}
50
159
  actions={
51
- <Link href="/projects" className="metric-card-anchor" style={{ minWidth: 240, display: 'block' }}>
52
- <div className="metric-card metric-card-green metric-card-link">
160
+ <Link href={primaryAction.href} className="metric-card-anchor" style={{ minWidth: 260, display: 'block' }}>
161
+ <div className={`metric-card metric-card-${primaryAction.tone} metric-card-link`}>
53
162
  <div className="metric-card-header">
54
163
  <div>
55
- <div className="metric-card-label">Next workflow</div>
56
- <div className="metric-card-value" style={{ fontSize: 24 }}>Setup a project</div>
164
+ <div className="metric-card-label">Priority now</div>
165
+ <div className="metric-card-value" style={{ fontSize: 24 }}>{primaryAction.title}</div>
57
166
  </div>
58
167
  <div className="metric-card-icon">↗</div>
59
168
  </div>
60
- <div className="metric-card-sublabel">Analyze a folder or GitHub repo, match skills, and identify capability gaps.</div>
169
+ <div className="metric-card-sublabel">{primaryAction.description}</div>
61
170
  </div>
62
171
  </Link>
63
172
  }
@@ -65,38 +174,98 @@ export default function Overview() {
65
174
 
66
175
  <OperatorLoopTrail surface="overview" />
67
176
 
68
- <div className="grid-5">
69
- <MetricCard label="Total skills" value={summary.skills.total} sublabel={`${summary.skills.evolved} evolved • ${summary.skillTests} skill tests`} tone="purple" href="/network" icon="◆" />
70
- <MetricCard label="Accepted proposals" value={summary.evolution.accepted} sublabel={`${summary.evolution.rejected} rejected`} tone="green" href="/evolution" icon="✓" />
177
+ <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(180px, 1fr))', gap: 16 }}>
71
178
  <MetricCard label="Unresolved corrections" value={summary.failures.unresolved} sublabel={`out of ${summary.failures.total} captured failures`} tone={summary.failures.unresolved > 0 ? 'yellow' : 'green'} href={summary.failures.unresolved > 0 ? '#attention' : '/evolution'} icon="!" />
72
- <MetricCard label="Discoveries" value={summary.buffer.discoveries} sublabel={`${summary.buffer.drafts} drafts in progress`} tone="blue" href="/research" icon="◎" />
73
- <MetricCard label="Frontier candidates" value={frontier.programs.length} sublabel={`${summary.canaries} active canaries`} tone="neutral" href="/frontier" icon="▲" />
74
179
  <MetricCard label="Proof review" value={proof.summary.reviewOpen} sublabel={`${proof.summary.effective} effective • ${proof.summary.regressed} regressed`} tone={proof.summary.reviewOpen > 0 ? 'yellow' : proof.summary.effective > 0 ? 'green' : 'neutral'} href="/proof" icon="◇" />
180
+ <MetricCard
181
+ label="Open pressure"
182
+ value={ontology.pressureLifecycle.open}
183
+ sublabel={`${ontology.pressureLifecycle.inProgress} in progress • ${ontology.pressureLifecycle.addressed} addressed`}
184
+ tone={ontology.pressureLifecycle.open > 0 ? 'yellow' : 'green'}
185
+ href="/coevolution"
186
+ icon="!"
187
+ />
188
+ <MetricCard
189
+ label="Topology review"
190
+ value={ontology.topologyReviews.open}
191
+ sublabel={`${ontology.topologyExecution.prepared} prepared • ${ontology.topologyExecution.applied} applied`}
192
+ tone={ontology.topologyReviews.open > 0 ? 'yellow' : ontology.topologyExecution.applied > 0 ? 'green' : 'blue'}
193
+ href="/topology"
194
+ icon="⇄"
195
+ />
196
+ <MetricCard
197
+ label="Ontology frontier"
198
+ value={ontology.ontologyLoop.frontier}
199
+ sublabel={`${ontology.ontologyLoop.reviewOpen} open • ${ontology.ontologyLoop.extensions} approved extensions`}
200
+ tone={ontology.ontologyLoop.reviewOpen > 0 ? 'yellow' : ontology.ontologyLoop.extensions > 0 ? 'blue' : 'neutral'}
201
+ href="/ontology"
202
+ icon="◎"
203
+ />
204
+ <MetricCard
205
+ label="Active semantic concepts"
206
+ value={ontology.ontologyLoop.adoption.activeConcepts}
207
+ sublabel={`${ontology.ontologyLoop.adoption.totalBindings} bindings • ${ontology.ontologyLoop.adoption.routesInfluenced} influenced routes`}
208
+ tone={ontology.ontologyLoop.adoption.activeConcepts > 0 ? 'green' : 'neutral'}
209
+ href="/ontology"
210
+ icon="⇄"
211
+ />
75
212
  </div>
76
213
 
77
214
  <SectionFrame
78
- eyebrow={`Release spotlight · v${CURRENT_RELEASE_SPOTLIGHT.version}`}
79
- title={CURRENT_RELEASE_SPOTLIGHT.title}
80
- description={CURRENT_RELEASE_SPOTLIGHT.summary}
215
+ eyebrow="Priority now"
216
+ title="Top ranked next actions"
217
+ description="This layer compresses the live loop into the most important operator moves right now instead of leaving everything as flat dashboard signal."
81
218
  tone="blue"
82
219
  >
83
- <div className="grid-2" style={{ gap: 16 }}>
84
- <div style={{ display: 'grid', gap: 10 }}>
85
- {CURRENT_RELEASE_SPOTLIGHT.bullets.map((item) => (
86
- <div key={item} className="signal-text">• {item}</div>
87
- ))}
88
- <div style={{ display: 'flex', gap: 8, flexWrap: 'wrap', marginTop: 4 }}>
89
- {CURRENT_RELEASE_SPOTLIGHT.nextActions.map((action) => (
90
- <Link key={action.href} href={action.href} className={`hero-chip hero-chip-${action.tone}`} style={{ textDecoration: 'none' }}>
91
- {action.label}
92
- </Link>
93
- ))}
94
- </div>
95
- </div>
96
- <SurfaceJumpLinks surface="overview" variant="panel" title="Jump into the updated loop" />
220
+ <div className="summary-list">
221
+ {priorityActions.map((action, index) => (
222
+ <Link key={`${action.href}-${index}`} href={action.href} className="summary-row">
223
+ <div className="summary-row-main">
224
+ <div className="summary-row-title">{index + 1}. {action.title}</div>
225
+ <div className="summary-row-meta">{action.description}</div>
226
+ </div>
227
+ <span className={`hero-chip hero-chip-${action.tone}`}>open</span>
228
+ </Link>
229
+ ))}
97
230
  </div>
98
231
  </SectionFrame>
99
232
 
233
+ {unresolved.length > 0 ? (
234
+ <SectionFrame
235
+ eyebrow="Attention"
236
+ title="Unresolved corrections"
237
+ description="These user corrections have been captured but not yet folded back into the skill network."
238
+ tone="yellow"
239
+ className="anchor-target"
240
+ >
241
+ <div id="attention" className="signal-list">
242
+ {unresolved.slice(0, 5).map((failure, index) => (
243
+ <div key={`${failure.id}-${index}`} className="signal-row signal-row-attention">
244
+ <div className="signal-dot" />
245
+ <div style={{ flex: 1 }}>
246
+ <div className="signal-title">
247
+ {failure.userRequest.slice(0, 120)}
248
+ {failure.userRequest.length > 120 ? '…' : ''}
249
+ </div>
250
+ <div className="signal-text">
251
+ Correction: {failure.correction.slice(0, 180)}
252
+ {failure.correction.length > 180 ? '…' : ''}
253
+ </div>
254
+ <div style={{ display: 'flex', gap: 8, flexWrap: 'wrap', marginTop: 10 }}>
255
+ <span className="badge badge-yellow">{failure.correctionType}</span>
256
+ {failure.project ? <span className="badge badge-gray">{failure.project}</span> : null}
257
+ <span className="badge badge-gray">{new Date(failure.timestamp).toLocaleDateString()}</span>
258
+ </div>
259
+ </div>
260
+ </div>
261
+ ))}
262
+ {unresolved.length > 5 ? (
263
+ <div className="signal-text" style={{ textAlign: 'center' }}>+{unresolved.length - 5} more unresolved corrections</div>
264
+ ) : null}
265
+ </div>
266
+ </SectionFrame>
267
+ ) : null}
268
+
100
269
  <SectionFrame
101
270
  eyebrow="Execution layer"
102
271
  title="Quick actions"
@@ -112,37 +281,60 @@ export default function Overview() {
112
281
  />
113
282
  </SectionFrame>
114
283
 
284
+ {showProviderAttention ? (
285
+ <SectionFrame
286
+ eyebrow={providerAttentionEyebrow}
287
+ title={providerAttentionTitle}
288
+ description={providerAttentionDescription}
289
+ tone={providerAttentionTone}
290
+ actions={<Link href="/commands" className="badge badge-gray">Open commands</Link>}
291
+ >
292
+ <div className="grid-2" style={{ gap: 16 }}>
293
+ <div className="summary-list">
294
+ {(['claude-code', 'codex', 'ollama'] as const).map((provider) => {
295
+ const snapshot = llmRuntime.providers[provider]
296
+ return (
297
+ <div key={provider} className="summary-row">
298
+ <div className="summary-row-main">
299
+ <div className="summary-row-title">{providerLabel(provider)}</div>
300
+ <div className="summary-row-meta">{snapshot.summary}</div>
301
+ {snapshot.nextStep ? <div className="summary-row-meta" style={{ marginTop: 6 }}>Next: {snapshot.nextStep}</div> : null}
302
+ </div>
303
+ <span className={`hero-chip hero-chip-${providerTone(snapshot.status)}`}>{snapshot.status}</span>
304
+ </div>
305
+ )
306
+ })}
307
+ </div>
308
+ <div style={{ display: 'grid', gap: 12 }}>
309
+ <MetricCard
310
+ label="Default provider"
311
+ value={providerLabel(llmRuntime.defaultProvider)}
312
+ sublabel={`fallback: ${llmRuntime.fallbackPolicy}${llmRuntime.fallbackOrder.length > 0 ? ` • ${llmRuntime.fallbackOrder.map((provider) => providerLabel(provider)).join(' → ')}` : ''}`}
313
+ tone={providerTone(defaultProvider.status)}
314
+ href="/commands"
315
+ icon="☍"
316
+ />
317
+ <MetricCard
318
+ label="Last provider run"
319
+ value={llmRuntime.lastExecution?.usedProvider ? providerLabel(llmRuntime.lastExecution.usedProvider) : 'None'}
320
+ sublabel={llmRuntime.lastExecution ? llmRuntime.lastExecution.summary : 'No provider-backed execution has been recorded yet.'}
321
+ tone={llmRuntime.lastExecution?.success ? 'green' : llmRuntime.lastExecution ? 'yellow' : 'neutral'}
322
+ href="/commands"
323
+ icon="↺"
324
+ />
325
+ <div className="signal-text">Commands, status, and dashboard surfaces now track whether execution stayed on the selected provider, degraded, or used an explicit fallback path.</div>
326
+ </div>
327
+ </div>
328
+ </SectionFrame>
329
+ ) : null}
330
+
115
331
  <SectionFrame
116
- eyebrow="Brain foundation"
332
+ eyebrow="Brain summary"
117
333
  title="Semantic backbone"
118
- description="A hybrid ontology view of the living brain, combining derived skill-graph semantics with native ontology frontier, extension, and semantic review activity."
334
+ description="Compact summary of pressure, response, structural review, ontology growth, and semantic adoption across the living brain."
119
335
  actions={<span className="badge badge-gray">{ontology.source === 'hybrid-native-derived' ? `Ontology ${ontology.specVersion} · hybrid native + derived` : ontology.source === 'graph' ? `Ontology ${ontology.specVersion}` : 'Compatibility-derived'}</span>}
120
336
  >
121
337
  <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(180px, 1fr))', gap: 16 }}>
122
- <MetricCard
123
- label="Generalist skills"
124
- value={ontology.skillRoles.generalist}
125
- sublabel={`${ontology.stabilityStates.stable} stable abstractions`}
126
- tone="purple"
127
- href="/network"
128
- icon="◎"
129
- />
130
- <MetricCard
131
- label="Project specialists"
132
- value={ontology.skillRoles.specialist}
133
- sublabel={`${ontology.plasticityStates.candidate} candidate rewires`}
134
- tone="blue"
135
- href="/projects"
136
- icon="◉"
137
- />
138
- <MetricCard
139
- label="Hybrid bridges"
140
- value={ontology.skillRoles.hybrid}
141
- sublabel={`${ontology.plasticityStates.volatile} volatile transitions`}
142
- tone="green"
143
- href="/network"
144
- icon="⇄"
145
- />
146
338
  <MetricCard
147
339
  label="Open pressure"
148
340
  value={ontology.pressureLifecycle.open}
@@ -159,14 +351,6 @@ export default function Overview() {
159
351
  href="/coevolution"
160
352
  icon="↺"
161
353
  />
162
- <MetricCard
163
- label="Pressure motifs"
164
- value={ontology.pressureMotifs.total}
165
- sublabel={`${ontology.pressureMotifs.promotionReady} promotion-ready • ${ontology.transferEvents.realized} realized transfers`}
166
- tone="purple"
167
- href="/coevolution"
168
- icon="⇄"
169
- />
170
354
  <MetricCard
171
355
  label="Topology review"
172
356
  value={ontology.topologyReviews.open}
@@ -191,81 +375,16 @@ export default function Overview() {
191
375
  href="/ontology"
192
376
  icon="⇄"
193
377
  />
194
- <MetricCard
195
- label="Observed mutation verbs"
196
- value={ontology.mutationOperationsObserved}
197
- sublabel={ontology.observedMutationActions.length > 0 ? ontology.observedMutationActions.join(' • ') : 'Waiting for evolution history'}
198
- tone="yellow"
199
- href="/evolution"
200
- icon="◇"
201
- />
202
378
  </div>
203
379
 
204
380
  <div style={{ display: 'flex', gap: 8, flexWrap: 'wrap', marginTop: 16 }}>
205
- <span className="badge badge-gray">{ontology.relationFamiliesObserved} relation families live in the graph</span>
206
- <span className="badge badge-gray">{ontology.evidenceBackedProposals} proposals already carry judge + regression evidence</span>
207
- <span className="badge badge-gray">{ontology.artifacts.total} evolution artifacts ({ontology.artifacts.native} native • {ontology.artifacts.derived} derived)</span>
208
- <span className="badge badge-gray">{ontology.activationTraces.total} activation traces ({ontology.activationTraces.native} native • {ontology.activationTraces.derived} derived)</span>
209
- <span className="badge badge-gray">{ontology.pressureSignals.total} pressure signals ({ontology.pressureSignals.native} native • {ontology.pressureSignals.derived} derived)</span>
210
- <span className="badge badge-gray">{ontology.pressureInterventions.total} response interventions logged</span>
211
- <span className="badge badge-gray">{ontology.pressureLifecycle.open} open • {ontology.pressureLifecycle.inProgress} in progress • {ontology.pressureLifecycle.addressed} addressed</span>
212
381
  <Link href="/coevolution" className="badge badge-blue" style={{ textDecoration: 'none' }}>Open co-evolution control</Link>
213
- <span className="badge badge-gray">{coevolution.topProjects.length} pressured project hotspots</span>
214
- <span className="badge badge-gray">{coevolution.crossProjectGapAreas.length} cross-project gap motifs</span>
215
- <span className="badge badge-gray">{ontology.pressureMotifs.promotionReady} motifs currently recommend generalize</span>
216
- <span className="badge badge-gray">{ontology.transferEvents.total} transfer events logged ({ontology.transferEvents.realized} realized)</span>
217
- <span className="badge badge-gray">ontology → {ontology.ontologyLoop.frontier} frontier • {ontology.ontologyLoop.extensions} extensions • {ontology.ontologyLoop.changeEvents} changes</span>
218
- <span className="badge badge-gray">semantic adoption → {ontology.ontologyLoop.adoption.activeConcepts} active concepts • {ontology.ontologyLoop.adoption.totalBindings} bindings • {ontology.ontologyLoop.adoption.routesInfluenced} influenced routes</span>
219
- <span className="badge badge-gray">deprecation risk → {ontology.ontologyLoop.adoption.conceptsAtDeprecationRisk} concepts • {ontology.ontologyLoop.adoption.unusedExtensions} unused extensions</span>
220
- <span className="badge badge-gray">topology → {ontology.topologyReviews.open} open • {ontology.topologyReviews.accepted} accepted • {ontology.topologyReviews.generatedFromManualReview} manual-route</span>
221
- <span className="badge badge-gray">execution → {ontology.topologyExecution.prepared} prepared • {ontology.topologyExecution.applied} applied • {ontology.topologyExecution.rolledBack} rolled back</span>
222
- <span className="badge badge-gray">proof → {proof.summary.total} total • {proof.summary.effective} effective • {proof.summary.reviewOpen} open review</span>
223
382
  <Link href="/ontology" className="badge badge-blue" style={{ textDecoration: 'none' }}>Open ontology control</Link>
224
383
  <Link href="/topology" className="badge badge-blue" style={{ textDecoration: 'none' }}>Open topology control</Link>
225
384
  <Link href="/proof" className="badge badge-blue" style={{ textDecoration: 'none' }}>Open proof control</Link>
226
- <span className="badge badge-gray">governance: {ontology.governance.activeMode.replace(/-/g, ' ')} ({ontology.governance.source})</span>
227
- <span className="badge badge-gray">routes → research {ontology.governedRoutes.research} • specialize {ontology.governedRoutes.specialize} • evolve {ontology.governedRoutes.evolve} • generalize {ontology.governedRoutes.generalize} • manual-review {ontology.governedRoutes['manual-review']}</span>
228
- <span className="badge badge-gray">{ontology.enrichedSkillNodes} skills carry explicit brain metadata</span>
229
- <span className="badge badge-gray">{ontology.annotatedFailures.pressureSignals} failures annotated with pressure signals</span>
230
385
  </div>
231
386
  </SectionFrame>
232
387
 
233
- {unresolved.length > 0 ? (
234
- <SectionFrame
235
- eyebrow="Attention"
236
- title="Unresolved corrections"
237
- description="These user corrections have been captured but not yet folded back into the skill network."
238
- tone="yellow"
239
- className="anchor-target"
240
- >
241
- <div id="attention" className="signal-list">
242
- {unresolved.slice(0, 5).map((failure, index) => (
243
- <div key={`${failure.id}-${index}`} className="signal-row signal-row-attention">
244
- <div className="signal-dot" />
245
- <div style={{ flex: 1 }}>
246
- <div className="signal-title">
247
- {failure.userRequest.slice(0, 120)}
248
- {failure.userRequest.length > 120 ? '…' : ''}
249
- </div>
250
- <div className="signal-text">
251
- Correction: {failure.correction.slice(0, 180)}
252
- {failure.correction.length > 180 ? '…' : ''}
253
- </div>
254
- <div style={{ display: 'flex', gap: 8, flexWrap: 'wrap', marginTop: 10 }}>
255
- <span className="badge badge-yellow">{failure.correctionType}</span>
256
- {failure.project ? <span className="badge badge-gray">{failure.project}</span> : null}
257
- <span className="badge badge-gray">{new Date(failure.timestamp).toLocaleDateString()}</span>
258
- </div>
259
- </div>
260
- </div>
261
- ))}
262
- {unresolved.length > 5 ? (
263
- <div className="signal-text" style={{ textAlign: 'center' }}>+{unresolved.length - 5} more unresolved corrections</div>
264
- ) : null}
265
- </div>
266
- </SectionFrame>
267
- ) : null}
268
-
269
388
  <div className="grid-2">
270
389
  <SectionFrame
271
390
  eyebrow="Frontier"
@@ -51,11 +51,42 @@ function consoleTone(state: RunState): 'neutral' | 'green' | 'red' | 'yellow' {
51
51
  return 'neutral'
52
52
  }
53
53
 
54
+ function getRecommendedProofMove(dashboard: ProofDashboardSummary) {
55
+ const firstOpen = dashboard.reviewQueue[0]
56
+ if (firstOpen) {
57
+ return {
58
+ label: 'Review queue first',
59
+ title: firstOpen.title,
60
+ copy: 'Open proof records should usually be resolved before you treat the prove layer as settled. Verify, defer, or contest the most important record first.',
61
+ }
62
+ }
63
+ if (dashboard.summary.regressed > 0) {
64
+ return {
65
+ label: 'Investigate regressed evidence',
66
+ title: 'A regressed outcome needs explanation before retry',
67
+ copy: 'Regressed records mean HelixEvo has explicit negative evidence. Inspect the linked structural or intervention path before repeating the same move.',
68
+ }
69
+ }
70
+ if (dashboard.summary.measuring > 0) {
71
+ return {
72
+ label: 'Let evidence mature',
73
+ title: 'Measuring means live, not yet proven',
74
+ copy: 'A measuring record is active but still too recent or incomplete for a stronger claim. Let downstream evidence accumulate before over-interpreting it.',
75
+ }
76
+ }
77
+ return {
78
+ label: 'Seed proof',
79
+ title: 'No proof targets yet',
80
+ copy: 'Proof becomes useful after live interventions, semantic adoption, transfer, or topology execution create evaluable downstream evidence.',
81
+ }
82
+ }
83
+
54
84
  export default function ProofClient({ initialDashboard }: { initialDashboard: ProofDashboardSummary }) {
55
85
  const [dashboard, setDashboard] = useState(initialDashboard)
56
86
  const [runState, setRunState] = useState<RunState>('idle')
57
87
  const [output, setOutput] = useState('')
58
88
  const [pendingKey, setPendingKey] = useState<string | null>(null)
89
+ const recommendedMove = getRecommendedProofMove(dashboard)
59
90
 
60
91
  const runReview = async (recordId: string, decision: ProofReviewDecisionStatus, label: string) => {
61
92
  setPendingKey(recordId)
@@ -106,9 +137,9 @@ export default function ProofClient({ initialDashboard }: { initialDashboard: Pr
106
137
  actions={
107
138
  <div style={{ display: 'grid', gap: 12 }}>
108
139
  <div className="hero-note-card">
109
- <div className="hero-note-label">Bounded proof layer</div>
110
- <div className="hero-note-title">Derived first, reviewed explicitly</div>
111
- <div className="hero-note-copy">The proof layer unifies evolution impact, semantic adoption, transfer, interventions, and topology execution without claiming direct causality when the evidence is only partial.</div>
140
+ <div className="hero-note-label">{recommendedMove.label}</div>
141
+ <div className="hero-note-title">{recommendedMove.title}</div>
142
+ <div className="hero-note-copy">{recommendedMove.copy}</div>
112
143
  </div>
113
144
  <SurfaceJumpLinks surface="proof" variant="compact" title="Proof handoffs" />
114
145
  </div>
@@ -125,6 +156,28 @@ export default function ProofClient({ initialDashboard }: { initialDashboard: Pr
125
156
  <MetricCard label="Open review" value={dashboard.summary.reviewOpen} sublabel={`${dashboard.summary.deferred} deferred • ${dashboard.summary.verified} verified`} tone={dashboard.summary.reviewOpen > 0 ? 'yellow' : 'green'} icon="◇" />
126
157
  </div>
127
158
 
159
+ <SectionFrame
160
+ eyebrow="Meaning"
161
+ title="What these proof states mean operationally"
162
+ description="Proof is only useful if the operator can tell what each state should trigger next. Measuring, regressed, and verified are not cosmetic labels — they change what HelixEvo should do next."
163
+ tone="blue"
164
+ >
165
+ <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(220px, 1fr))', gap: 12 }}>
166
+ <div className="guide-dimension-card" style={{ borderLeftColor: 'var(--blue)' }}>
167
+ <div style={{ fontSize: 12, fontWeight: 700, color: 'var(--text)' }}>Measuring</div>
168
+ <div style={{ fontSize: 12, color: 'var(--text-dim)', marginTop: 8, lineHeight: 1.7 }}>Live evidence exists, but HelixEvo should wait for more downstream signal before claiming success.</div>
169
+ </div>
170
+ <div className="guide-dimension-card" style={{ borderLeftColor: 'var(--yellow)' }}>
171
+ <div style={{ fontSize: 12, fontWeight: 700, color: 'var(--text)' }}>Regressed</div>
172
+ <div style={{ fontSize: 12, color: 'var(--text-dim)', marginTop: 8, lineHeight: 1.7 }}>A move created explicit negative evidence. Inspect the linked route or structural execution before retrying the same strategy.</div>
173
+ </div>
174
+ <div className="guide-dimension-card" style={{ borderLeftColor: 'var(--green)' }}>
175
+ <div style={{ fontSize: 12, fontWeight: 700, color: 'var(--text)' }}>Verified</div>
176
+ <div style={{ fontSize: 12, color: 'var(--text-dim)', marginTop: 8, lineHeight: 1.7 }}>An operator has reviewed the record explicitly. Verification increases trust in the review state, not necessarily in causal certainty.</div>
177
+ </div>
178
+ </div>
179
+ </SectionFrame>
180
+
128
181
  <SectionFrame
129
182
  eyebrow="Coverage"
130
183
  title="Proof now spans the live brain loop"
@@ -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"