Skip to content

Commit 3dce7d2

Browse files
feat: development timeline of project PRs
Scanned Daniil's, Dmytro's, and Marcin's GitHub for project-related PRs across nethermind / state-benchmarks / eth-perf-research (closed-unmerged excluded). New /timeline page: vertical month-grouped timeline of 18 PRs, each tagged by repo + author + status badge (merged / open / draft), linking to GitHub. Added Timeline to the nav.
1 parent 71b7c65 commit 3dce7d2

3 files changed

Lines changed: 108 additions & 0 deletions

File tree

site/src/components/Nav.astro

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ const links = [
66
{ href: `${base}/problems`, label: 'Problems' },
77
{ href: `${base}/design/overview`, label: 'Design' },
88
{ href: `${base}/results`, label: 'Results' },
9+
{ href: `${base}/timeline`, label: 'Timeline' },
910
{ href: `${base}/docs`, label: 'Docs' },
1011
{ href: `${base}/about`, label: 'About' },
1112
];

site/src/data/prs.json

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
{
2+
"note": "Project pull requests by the three contributors across the three repos. Closed-unmerged PRs are excluded. Dates are when each PR was opened; the badge shows current status. Generated from a GitHub scan on 2026-06-18.",
3+
"repos": {
4+
"nethermind": "NethermindEth/nethermind",
5+
"state-benchmarks": "NethermindEth/state-benchmarks",
6+
"eth-perf-research": "NethermindEth/eth-perf-research"
7+
},
8+
"prs": [
9+
{ "date": "2026-06-18", "repo": "nethermind", "number": 12059, "status": "draft", "author": "Daniil", "title": "rlpx: snapshot MaxFrameSize per Encode to prevent torn-read frame corruption", "url": "https://github.com/NethermindEth/nethermind/pull/12059" },
10+
{ "date": "2026-06-16", "repo": "state-benchmarks", "number": 36, "status": "merged", "author": "Daniil", "title": "Mock consensus layer (Engine-API driver) for frozen-milestone snap-sync + replay", "url": "https://github.com/NethermindEth/state-benchmarks/pull/36" },
11+
{ "date": "2026-06-12", "repo": "nethermind", "number": 11981, "status": "merged", "author": "Daniil", "title": "Merge.Plugin: produce testing_commitBlockV1 blocks on the main world state", "url": "https://github.com/NethermindEth/nethermind/pull/11981" },
12+
{ "date": "2026-06-12", "repo": "state-benchmarks", "number": 34, "status": "draft", "author": "Dmytro", "title": "Locust-based benchmarking framework", "url": "https://github.com/NethermindEth/state-benchmarks/pull/34" },
13+
{ "date": "2026-06-09", "repo": "nethermind", "number": 11943, "status": "merged", "author": "Daniil", "title": "Sync.StaticSnapPivot — fixed-pivot snap sync from a frozen peer", "url": "https://github.com/NethermindEth/nethermind/pull/11943" },
14+
{ "date": "2026-05-27", "repo": "nethermind", "number": 11788, "status": "draft", "author": "Daniil", "title": "StateDiffsWriter — replace the StateComposition plugin (diff-only + Go sidecar)", "url": "https://github.com/NethermindEth/nethermind/pull/11788" },
15+
{ "date": "2026-05-25", "repo": "nethermind", "number": 11746, "status": "merged", "author": "Marcin", "title": "Validate FCU safe/finalized by ancestry when main-chain markers are outdated", "url": "https://github.com/NethermindEth/nethermind/pull/11746" },
16+
{ "date": "2026-05-19", "repo": "nethermind", "number": 11681, "status": "merged", "author": "Marcin", "title": "Fix forkchoice-update (FCU) validation order", "url": "https://github.com/NethermindEth/nethermind/pull/11681" },
17+
{ "date": "2026-05-13", "repo": "nethermind", "number": 11586, "status": "merged", "author": "Daniil", "title": "StateComposition: refuse to publish a partial-scan baseline", "url": "https://github.com/NethermindEth/nethermind/pull/11586" },
18+
{ "date": "2026-05-13", "repo": "nethermind", "number": 11593, "status": "merged", "author": "Daniil", "title": "Merge.Plugin: skip duplicate processing in testing_commitBlockV1", "url": "https://github.com/NethermindEth/nethermind/pull/11593" },
19+
{ "date": "2026-05-05", "repo": "nethermind", "number": 11498, "status": "merged", "author": "Daniil", "title": "Add proof_getProofWithMeta JSON-RPC method (witness instrumentation)", "url": "https://github.com/NethermindEth/nethermind/pull/11498" },
20+
{ "date": "2026-04-28", "repo": "nethermind", "number": 11385, "status": "merged", "author": "Daniil", "title": "testing_commitBlockV1 — commit a block on the chain head", "url": "https://github.com/NethermindEth/nethermind/pull/11385" },
21+
{ "date": "2026-04-28", "repo": "nethermind", "number": 11382, "status": "merged", "author": "Daniil", "title": "statecomp: serialize empty histograms, bootstrap on first new head", "url": "https://github.com/NethermindEth/nethermind/pull/11382" },
22+
{ "date": "2026-04-24", "repo": "eth-perf-research", "number": 77, "status": "draft", "author": "Daniil", "title": "Go bloating orchestrator + sidecar + cross-EL replay", "url": "https://github.com/NethermindEth/eth-perf-research/pull/77" },
23+
{ "date": "2026-04-21", "repo": "nethermind", "number": 11280, "status": "merged", "author": "Daniil", "title": "Serialize testing_commitBlockV1 payload with EthereumJsonSerializer", "url": "https://github.com/NethermindEth/nethermind/pull/11280" },
24+
{ "date": "2026-04-20", "repo": "nethermind", "number": 11254, "status": "merged", "author": "Daniil", "title": "HistoryPruner: self-bootstrap in TryPruneHistory", "url": "https://github.com/NethermindEth/nethermind/pull/11254" },
25+
{ "date": "2026-04-06", "repo": "nethermind", "number": 11050, "status": "merged", "author": "Daniil", "title": "Snap-serving fixes (×4): path-group limit, ISnapServer DI, SnapServingEnabled CLI override, 2 MB message limit", "url": "https://github.com/NethermindEth/nethermind/pulls?q=is%3Apr+author%3AAnkushinDaniil+11050+11051+11052+11053" },
26+
{ "date": "2026-03-30", "repo": "nethermind", "number": 10995, "status": "merged", "author": "Daniil", "title": "StateComposition plugin — real-time state metrics with incremental tracking (the original sensor)", "url": "https://github.com/NethermindEth/nethermind/pull/10995" }
27+
]
28+
}

site/src/pages/timeline.astro

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
---
2+
import BaseLayout from '../layouts/BaseLayout.astro';
3+
import Section from '../components/Section.astro';
4+
import prs from '../data/prs.json';
5+
6+
const STATUS: Record<string, { label: string; dot: string; badge: string }> = {
7+
merged: { label: 'merged', dot: 'bg-signal-good', badge: 'bg-signal-good/15 text-signal-good' },
8+
open: { label: 'open', dot: 'bg-accent-500', badge: 'bg-accent-500/15 text-accent-400' },
9+
draft: { label: 'draft', dot: 'bg-ink-500', badge: 'bg-ink-800 text-ink-300' },
10+
};
11+
const REPO_TAG: Record<string, string> = {
12+
nethermind: 'nethermind',
13+
'state-benchmarks': 'state-benchmarks',
14+
'eth-perf-research': 'eth-perf-research',
15+
};
16+
const monthName = (d: string) =>
17+
new Date(d + 'T00:00:00Z').toLocaleDateString('en-US', { month: 'long', year: 'numeric', timeZone: 'UTC' });
18+
const dayLabel = (d: string) =>
19+
new Date(d + 'T00:00:00Z').toLocaleDateString('en-US', { month: 'short', day: 'numeric', timeZone: 'UTC' });
20+
21+
// group preserving the data's newest-first order
22+
const months: { name: string; items: typeof prs.prs }[] = [];
23+
for (const pr of prs.prs) {
24+
const m = monthName(pr.date);
25+
let bucket = months.find((x) => x.name === m);
26+
if (!bucket) { bucket = { name: m, items: [] }; months.push(bucket); }
27+
bucket.items.push(pr);
28+
}
29+
30+
const counts = {
31+
merged: prs.prs.filter((p) => p.status === 'merged').length,
32+
open: prs.prs.filter((p) => p.status === 'open').length,
33+
draft: prs.prs.filter((p) => p.status === 'draft').length,
34+
};
35+
const authors = [...new Set(prs.prs.map((p) => p.author))];
36+
---
37+
<BaseLayout title="Timeline" description="Development timeline — the project pull requests across Nethermind, the orchestrator, and the benchmark repo.">
38+
<Section
39+
eyebrow="Timeline"
40+
title="How the rig got built."
41+
intro="The project's pull requests across the three repos, newest first. Engine instrumentation and snap-sync land in Nethermind; the orchestrator and benchmark tooling live in their own repos. Closed-without-merge PRs are omitted."
42+
>
43+
<div class="flex flex-wrap gap-3 text-sm">
44+
<span class="inline-flex items-center gap-2 rounded-full border border-ink-800 px-3 py-1"><span class="size-2 rounded-full bg-signal-good"></span>{counts.merged} merged</span>
45+
{counts.open > 0 && <span class="inline-flex items-center gap-2 rounded-full border border-ink-800 px-3 py-1"><span class="size-2 rounded-full bg-accent-500"></span>{counts.open} open</span>}
46+
<span class="inline-flex items-center gap-2 rounded-full border border-ink-800 px-3 py-1"><span class="size-2 rounded-full bg-ink-500"></span>{counts.draft} draft</span>
47+
<span class="inline-flex items-center gap-2 rounded-full border border-ink-800 px-3 py-1 text-ink-400">contributors: {authors.join(', ')}</span>
48+
</div>
49+
50+
<div class="mt-10">
51+
{months.map((month) => (
52+
<div class="mb-10">
53+
<h3 class="font-display text-lg text-accent-400 mb-4">{month.name}</h3>
54+
<ol class="relative border-l border-ink-800 ml-2">
55+
{month.items.map((pr) => {
56+
const s = STATUS[pr.status] ?? STATUS.draft;
57+
return (
58+
<li class="relative pl-6 pb-6 last:pb-0">
59+
<span class:list={['absolute -left-[5px] top-1.5 size-2.5 rounded-full ring-4 ring-ink-950', s.dot]}></span>
60+
<div class="flex flex-wrap items-center gap-x-3 gap-y-1">
61+
<span class="font-mono text-xs text-ink-500 tabular-nums">{dayLabel(pr.date)}</span>
62+
<span class="font-mono text-xs px-1.5 py-0.5 rounded bg-ink-900 border border-ink-800 text-ink-400">{REPO_TAG[pr.repo]}</span>
63+
<span class:list={['font-mono text-xs px-1.5 py-0.5 rounded', s.badge]}>{s.label}</span>
64+
</div>
65+
<a href={pr.url} target="_blank" rel="noreferrer noopener" class="mt-1.5 block text-ink-100 hover:text-accent-400 transition-colors">
66+
<span class="font-mono text-ink-500">#{pr.number}</span> {pr.title}
67+
</a>
68+
<div class="mt-0.5 text-xs text-ink-500">{pr.author}</div>
69+
</li>
70+
);
71+
})}
72+
</ol>
73+
</div>
74+
))}
75+
</div>
76+
77+
<p class="mt-6 text-sm text-ink-400">{prs.note}</p>
78+
</Section>
79+
</BaseLayout>

0 commit comments

Comments
 (0)