Skip to content

Commit c2567a0

Browse files
ccerv1claude
andcommitted
fix: move accordion cells to bottom of files for correct render order in static export
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 9d4d487 commit c2567a0

3 files changed

Lines changed: 101 additions & 103 deletions

File tree

notebooks/insights/defi-builder-journeys.py

Lines changed: 45 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1327,52 +1327,6 @@ def transform_pipeline_composition(
13271327
return (pipeline_by_eco,)
13281328

13291329

1330-
@app.cell(hide_code=True)
1331-
def section_conclusion(mo, pipeline_by_eco):
1332-
# pipeline_by_eco dependency ensures this renders after all content cells
1333-
mo.accordion({
1334-
"Metrics & Definitions": mo.md("""
1335-
- Ecosystem Classification:
1336-
- Ethereum: Projects with >80% of TVL on Ethereum (L1 + L2s like Arbitrum, Polygon, Base, Optimism, etc.)
1337-
- Solana: Projects whose top chain by TVL is Solana
1338-
- Other: Remaining non-Ethereum, non-Solana projects (including Hyperliquid, Bitcoin, etc.)
1339-
- Project Classifications:
1340-
- Home Project: The DeFi project a builder is primarily associated with, based on their most active repository contributions.
1341-
- Feeder Projects: Projects where a builder contributed or starred repositories before onboarding to their home DeFi project.
1342-
- Builder Classifications:
1343-
- Qualifying Builder: A builder with 12+ months of sustained contribution to a top DeFi project's home repositories.
1344-
- Monthly Active Builders (MABs): Count of unique qualified builders with at least one contribution event in a given month.
1345-
- Newcomer: A qualified builder with fewer than 6 months of observable open-source activity before onboarding to their home project (came in cold).
1346-
- Cohort Retention: The percentage of builders from a given onboarding cohort (year) who remain active on their home project at each subsequent time interval.
1347-
- Lifecycle:
1348-
- Onboarding: A builder's first month of activity on their home project.
1349-
- Offboarding: A builder is considered offboarded if they have been inactive on their home project for 6+ consecutive months.
1350-
- Still Active: A builder who has contributed to their home project within the most recent 6 months of data.
1351-
- Flows:
1352-
- Net Flow: The year-over-year difference between builders entering and exiting an ecosystem. Positive means net talent gain.
1353-
- Cross-Ecosystem Flow (Ethereum <-> Other Crypto): The horizontal bar in the Net Flows section counts unique builders who moved between Ethereum and other crypto ecosystems over the full time period. This uses a different method from the annual inflow/outflow bars, which count year-over-year flows by source/destination category; the two methods do not sum to each other.
1354-
- Year-over-Year Flows: The annual bar chart breaks down builder inflows (entering) and outflows (leaving) by partner category (Other Crypto, Non-Crypto OSS, Inactive). The net flow line shows the cumulative balance; these year-over-year counts sum to the total net flow shown in the stat cards.
1355-
"""),
1356-
"Assumptions & Limitations": mo.md("""
1357-
- TVL as inclusion criterion: We use TVL to identify economically meaningful protocols, which excludes low-stakes forks and testnet-only experiments; this analysis focuses on capital-securing DeFi.
1358-
- Excluded protocols: Some high-TVL protocols have minimal observable OSS activity, so they may appear in tables but contribute little to flow analysis.
1359-
- Private repositories: Activity in private repos is not visible to GitHub Archive, so teams that develop behind closed doors (or move to private repos after open-source phases) may appear to go inactive; this is one of the most consequential limitations.
1360-
- Post-hire behavior: Some builders are hired by crypto firms and stop public contributions, so the inactive count may be inflated; we cannot distinguish left crypto from went private.
1361-
- Bot and noise filtering: We exclude known bots, but some automated contributions may still slip through.
1362-
- Identity resolution: OpenDevData maps multiple accounts to canonical IDs, but imperfect mapping may double-count some builders.
1363-
- Scope: This is a structured analysis of visible OSS builder flows across economically significant DeFi protocols, not a census of all crypto builders or proprietary development.
1364-
"""),
1365-
"Data Sources": mo.md("""
1366-
- [DefiLlama](https://defillama.com/) --- Top DeFi protocols by TVL (40 selected)
1367-
- [OSS Directory](https://github.com/opensource-observer/oss-directory) --- Protocol to GitHub mapping
1368-
- [OpenDevData (Electric Capital)](https://github.com/electric-capital/crypto-ecosystems) --- Ecosystem classifications
1369-
- [GitHub Archive](https://www.gharchive.org/) --- Builder activity events
1370-
- [OSO API](https://docs.oso.xyz/) --- Data pipeline and metrics
1371-
"""),
1372-
})
1373-
return
1374-
1375-
13761330
@app.cell(hide_code=True)
13771331
def settings_color_palette():
13781332
# Color palette — semantic colors reused across all charts
@@ -1460,6 +1414,51 @@ def import_libraries():
14601414
return go, make_subplots, pd
14611415

14621416

1417+
@app.cell(hide_code=True)
1418+
def section_conclusion(mo):
1419+
mo.accordion({
1420+
"Metrics & Definitions": mo.md("""
1421+
- Ecosystem Classification:
1422+
- Ethereum: Projects with >80% of TVL on Ethereum (L1 + L2s like Arbitrum, Polygon, Base, Optimism, etc.)
1423+
- Solana: Projects whose top chain by TVL is Solana
1424+
- Other: Remaining non-Ethereum, non-Solana projects (including Hyperliquid, Bitcoin, etc.)
1425+
- Project Classifications:
1426+
- Home Project: The DeFi project a builder is primarily associated with, based on their most active repository contributions.
1427+
- Feeder Projects: Projects where a builder contributed or starred repositories before onboarding to their home DeFi project.
1428+
- Builder Classifications:
1429+
- Qualifying Builder: A builder with 12+ months of sustained contribution to a top DeFi project's home repositories.
1430+
- Monthly Active Builders (MABs): Count of unique qualified builders with at least one contribution event in a given month.
1431+
- Newcomer: A qualified builder with fewer than 6 months of observable open-source activity before onboarding to their home project (came in cold).
1432+
- Cohort Retention: The percentage of builders from a given onboarding cohort (year) who remain active on their home project at each subsequent time interval.
1433+
- Lifecycle:
1434+
- Onboarding: A builder's first month of activity on their home project.
1435+
- Offboarding: A builder is considered offboarded if they have been inactive on their home project for 6+ consecutive months.
1436+
- Still Active: A builder who has contributed to their home project within the most recent 6 months of data.
1437+
- Flows:
1438+
- Net Flow: The year-over-year difference between builders entering and exiting an ecosystem. Positive means net talent gain.
1439+
- Cross-Ecosystem Flow (Ethereum <-> Other Crypto): The horizontal bar in the Net Flows section counts unique builders who moved between Ethereum and other crypto ecosystems over the full time period. This uses a different method from the annual inflow/outflow bars, which count year-over-year flows by source/destination category; the two methods do not sum to each other.
1440+
- Year-over-Year Flows: The annual bar chart breaks down builder inflows (entering) and outflows (leaving) by partner category (Other Crypto, Non-Crypto OSS, Inactive). The net flow line shows the cumulative balance; these year-over-year counts sum to the total net flow shown in the stat cards.
1441+
"""),
1442+
"Assumptions & Limitations": mo.md("""
1443+
- TVL as inclusion criterion: We use TVL to identify economically meaningful protocols, which excludes low-stakes forks and testnet-only experiments; this analysis focuses on capital-securing DeFi.
1444+
- Excluded protocols: Some high-TVL protocols have minimal observable OSS activity, so they may appear in tables but contribute little to flow analysis.
1445+
- Private repositories: Activity in private repos is not visible to GitHub Archive, so teams that develop behind closed doors (or move to private repos after open-source phases) may appear to go inactive; this is one of the most consequential limitations.
1446+
- Post-hire behavior: Some builders are hired by crypto firms and stop public contributions, so the inactive count may be inflated; we cannot distinguish left crypto from went private.
1447+
- Bot and noise filtering: We exclude known bots, but some automated contributions may still slip through.
1448+
- Identity resolution: OpenDevData maps multiple accounts to canonical IDs, but imperfect mapping may double-count some builders.
1449+
- Scope: This is a structured analysis of visible OSS builder flows across economically significant DeFi protocols, not a census of all crypto builders or proprietary development.
1450+
"""),
1451+
"Data Sources": mo.md("""
1452+
- [DefiLlama](https://defillama.com/) --- Top DeFi protocols by TVL (40 selected)
1453+
- [OSS Directory](https://github.com/opensource-observer/oss-directory) --- Protocol to GitHub mapping
1454+
- [OpenDevData (Electric Capital)](https://github.com/electric-capital/crypto-ecosystems) --- Ecosystem classifications
1455+
- [GitHub Archive](https://www.gharchive.org/) --- Builder activity events
1456+
- [OSO API](https://docs.oso.xyz/) --- Data pipeline and metrics
1457+
"""),
1458+
})
1459+
return
1460+
1461+
14631462
@app.cell(hide_code=True)
14641463
def setup_pyoso():
14651464
# This code sets up pyoso to be used as a database provider for this notebook

notebooks/insights/developer-report-2025.py

Lines changed: 25 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -10,30 +10,6 @@ def header_title(mo):
1010
return
1111

1212

13-
@app.cell(hide_code=True)
14-
def header_accordion(mo, _report_complete):
15-
mo.accordion({
16-
"Metrics & Definitions": mo.md("""
17-
- **Time period**: January 2015 to December 2025 (full historical data)
18-
- **Monthly Active Developer (MAD)**: A developer who authored at least 1 commit in a given month (measured using a 28-day rolling activity window)
19-
- **Tenure Categories**: Newcomers (< 1 year active), Emerging (1–2 years), Established (2+ years)
20-
- **Activity Levels**: Full-time (sustained activity over 84-day window), Part-time (intermittent), One-time (sporadic)
21-
"""),
22-
"Assumptions & Limitations": mo.md("""
23-
- **Commit-only activity measure**: Developer activity is based on commits only — pull requests, code reviews, and issue comments are not counted
24-
- **Public repos only**: Private repositories are excluded from the dataset
25-
- **Identity resolution**: Developer identities are resolved across forges using Electric Capital's methodology, but some cross-account connections may be missed
26-
- **Ecosystem classification**: Ecosystem assignments follow the Electric Capital taxonomy; projects may belong to multiple ecosystems
27-
"""),
28-
"Data Sources": mo.md("""
29-
- **Open Dev Data** — Electric Capital's developer activity dataset, [github.com/electric-capital/crypto-ecosystems](https://github.com/electric-capital/crypto-ecosystems)
30-
- **OSO API** — Data pipeline and metrics, [docs.oso.xyz](https://docs.oso.xyz/)
31-
- **Key Models** — `oso.stg_opendevdata__eco_mads`, `oso.stg_opendevdata__ecosystems`
32-
"""),
33-
})
34-
return
35-
36-
3713
@app.cell(hide_code=True)
3814
def setup_imports():
3915
import pandas as pd
@@ -1634,8 +1610,31 @@ def comparison_chart(df_all, mo, pd):
16341610
)
16351611
_src = _html_mod.escape(_inner, quote=True)
16361612
mo.Html(f'<iframe srcdoc="{_src}" class="ddp-chart-frame" scrolling="no"></iframe>')
1637-
_report_complete = True
1638-
return (_report_complete,)
1613+
return
1614+
1615+
1616+
@app.cell(hide_code=True)
1617+
def header_accordion(mo):
1618+
mo.accordion({
1619+
"Metrics & Definitions": mo.md("""
1620+
- **Time period**: January 2015 to December 2025 (full historical data)
1621+
- **Monthly Active Developer (MAD)**: A developer who authored at least 1 commit in a given month (measured using a 28-day rolling activity window)
1622+
- **Tenure Categories**: Newcomers (< 1 year active), Emerging (1–2 years), Established (2+ years)
1623+
- **Activity Levels**: Full-time (sustained activity over 84-day window), Part-time (intermittent), One-time (sporadic)
1624+
"""),
1625+
"Assumptions & Limitations": mo.md("""
1626+
- **Commit-only activity measure**: Developer activity is based on commits only — pull requests, code reviews, and issue comments are not counted
1627+
- **Public repos only**: Private repositories are excluded from the dataset
1628+
- **Identity resolution**: Developer identities are resolved across forges using Electric Capital's methodology, but some cross-account connections may be missed
1629+
- **Ecosystem classification**: Ecosystem assignments follow the Electric Capital taxonomy; projects may belong to multiple ecosystems
1630+
"""),
1631+
"Data Sources": mo.md("""
1632+
- **Open Dev Data** — Electric Capital's developer activity dataset, [github.com/electric-capital/crypto-ecosystems](https://github.com/electric-capital/crypto-ecosystems)
1633+
- **OSO API** — Data pipeline and metrics, [docs.oso.xyz](https://docs.oso.xyz/)
1634+
- **Key Models** — `oso.stg_opendevdata__eco_mads`, `oso.stg_opendevdata__ecosystems`
1635+
"""),
1636+
})
1637+
return
16391638

16401639

16411640
if __name__ == "__main__":

notebooks/insights/developer-retention.py

Lines changed: 31 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -12,37 +12,6 @@ def header_title(mo):
1212

1313

1414

15-
@app.cell(hide_code=True)
16-
def header_accordion(mo):
17-
mo.accordion({
18-
"Metrics & Definitions": mo.md("""
19-
**Definitions**
20-
21-
- **Cohort**: Developers grouped by the year of their first contribution to the ecosystem
22-
- **Retention Rate**: Percentage of the original cohort that remains active in subsequent periods
23-
- **Years Since Join**: Time elapsed since first contribution (Year 0 = joined year, always 100%)
24-
25-
**Methodology**
26-
27-
1. **Cohort Assignment**: Each developer is assigned to a cohort based on their first contribution date
28-
2. **Activity Tracking**: We track whether the developer had any activity in subsequent years
29-
3. **Retention Rate**: Percentage of the original cohort that remains active
30-
"""),
31-
"Assumptions & Limitations": mo.md("""
32-
- **Multi-ecosystem developers**: Developers active in multiple ecosystems are counted separately per ecosystem — a developer who churns from one ecosystem may still be active in another
33-
- **Identity resolution**: Developer identities are resolved by Electric Capital's fingerprinting; the same person using different accounts may be counted multiple times
34-
- **Newer cohorts**: More recent cohorts have shorter observation windows and therefore fewer data points for retention analysis
35-
- **Public commits only**: Only public GitHub activity is tracked; private repos and non-GitHub platforms are excluded
36-
- **Activity windows**: Activity is measured using 28-day rolling windows via Open Dev Data's `repo_developer_28d_activities` model
37-
"""),
38-
"Data Sources": mo.md("""
39-
- **Open Dev Data (Electric Capital)** — Developer activity data, [github.com/electric-capital/crypto-ecosystems](https://github.com/electric-capital/crypto-ecosystems)
40-
- **Key Models** — `oso.stg_opendevdata__repo_developer_28d_activities`, `oso.stg_opendevdata__ecosystems_repos_recursive`
41-
"""),
42-
})
43-
return
44-
45-
4615
@app.cell(hide_code=True)
4716
def test_connection(mo, pyoso_db_conn):
4817
_test_df = mo.sql("""SELECT 1 AS test""", engine=pyoso_db_conn, output=False)
@@ -478,6 +447,37 @@ def apply_ec_style(fig, title=None, subtitle=None, y_title=None, show_legend=Tru
478447
return (apply_ec_style,)
479448

480449

450+
@app.cell(hide_code=True)
451+
def header_accordion(mo):
452+
mo.accordion({
453+
"Metrics & Definitions": mo.md("""
454+
**Definitions**
455+
456+
- **Cohort**: Developers grouped by the year of their first contribution to the ecosystem
457+
- **Retention Rate**: Percentage of the original cohort that remains active in subsequent periods
458+
- **Years Since Join**: Time elapsed since first contribution (Year 0 = joined year, always 100%)
459+
460+
**Methodology**
461+
462+
1. **Cohort Assignment**: Each developer is assigned to a cohort based on their first contribution date
463+
2. **Activity Tracking**: We track whether the developer had any activity in subsequent years
464+
3. **Retention Rate**: Percentage of the original cohort that remains active
465+
"""),
466+
"Assumptions & Limitations": mo.md("""
467+
- **Multi-ecosystem developers**: Developers active in multiple ecosystems are counted separately per ecosystem — a developer who churns from one ecosystem may still be active in another
468+
- **Identity resolution**: Developer identities are resolved by Electric Capital's fingerprinting; the same person using different accounts may be counted multiple times
469+
- **Newer cohorts**: More recent cohorts have shorter observation windows and therefore fewer data points for retention analysis
470+
- **Public commits only**: Only public GitHub activity is tracked; private repos and non-GitHub platforms are excluded
471+
- **Activity windows**: Activity is measured using 28-day rolling windows via Open Dev Data's `repo_developer_28d_activities` model
472+
"""),
473+
"Data Sources": mo.md("""
474+
- **Open Dev Data (Electric Capital)** — Developer activity data, [github.com/electric-capital/crypto-ecosystems](https://github.com/electric-capital/crypto-ecosystems)
475+
- **Key Models** — `oso.stg_opendevdata__repo_developer_28d_activities`, `oso.stg_opendevdata__ecosystems_repos_recursive`
476+
"""),
477+
})
478+
return
479+
480+
481481
@app.cell(hide_code=True)
482482
def setup_pyoso():
483483
# This code sets up pyoso to be used as a database provider for this notebook

0 commit comments

Comments
 (0)