Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions scripts/collect_growth_metrics.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,9 +126,13 @@
}
REPORTER_WAITING_LABELS = {"needs feedback"}
CONTRIBUTOR_WAITING_LABELS = {"good first issue", "help wanted", "ready for PR"}
MANUAL_HANDOFF_ACTIONS = {
"submit Glama",
}
PASSIVE_INTEGRATION_ACTIONS = {
"archive",
"finish draft",
*MANUAL_HANDOFF_ACTIONS,
"preview auth gate",
"resolve CLA",
"wait for checks",
Expand Down Expand Up @@ -655,6 +659,24 @@ def format_integration_markdown(metrics: Dict[str, Any]) -> str:
f"- [{integration['pr']}]({integration.get('html_url')}): "
f"{integration.get('next_action') or 'inspect'}"
)
manual_handoff_integrations = sorted(
(
integration
for integration in metrics["integrations"]
if integration.get("state") == "open"
and (integration.get("next_action") or "inspect") in MANUAL_HANDOFF_ACTIONS
),
key=lambda integration: int(integration.get("repo_stars") or 0),
reverse=True,
)
Comment on lines +662 to +671

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The introduction of the ## Manual handoff gates section causes integrations like punkpeye/awesome-mcp-servers#7153 (which have both a manual handoff action and a known review gate reason) to be listed twice: once under ## Manual handoff gates and again under ## Manual review gates.

To avoid this redundancy and keep the report clean, we should filter out manual handoff integrations from the review_gate_integrations list. Since review_gate_integrations is defined on lines 680-682, you can update its definition to:

    review_gate_integrations = [
        integration for integration in metrics["integrations"]
        if integration.get("known_review_gate_reason")
        and (integration.get("next_action") or "inspect") not in MANUAL_HANDOFF_ACTIONS
    ]

if manual_handoff_integrations:
lines.extend(["", "## Manual handoff gates", ""])
for integration in manual_handoff_integrations:
reason = integration.get("known_review_gate_reason") or "manual action required"
lines.append(
f"- [{integration['pr']}]({integration.get('html_url')}): "
f"{integration.get('next_action') or 'inspect'}; {reason}"
)
review_gate_integrations = [
integration for integration in metrics["integrations"] if integration.get("known_review_gate_reason")
]
Expand Down
45 changes: 45 additions & 0 deletions tests/test_collect_growth_metrics.py
Original file line number Diff line number Diff line change
Expand Up @@ -1070,6 +1070,51 @@ def test_format_integration_markdown_lists_active_operator_queue():
assert "activepieces/activepieces#13985" not in active_queue


def test_format_integration_markdown_lists_manual_handoff_gates():
module = load_growth_metrics_module()
metrics = {
"collected_at_utc": "2026-07-02T00:00:00+00:00",
"integrations": [
{
"pr": "punkpeye/awesome-mcp-servers#7153",
"html_url": "https://github.com/punkpeye/awesome-mcp-servers/pull/7153",
"state": "open",
"mergeable_state": "clean",
"repo_stars": 90_000,
"repo_forks": 12_000,
"updated_at": "2026-06-16T04:21:55Z",
"updated_age_days": 16,
"next_action": "submit Glama",
"known_review_gate_reason": "Glama listing and score badge required before review",
"checks": {"state": "success", "failed_check_runs": [], "pending_check_runs": []},
},
{
"pr": "huggingface/optimum-intel#1801",
"html_url": "https://github.com/huggingface/optimum-intel/pull/1801",
"state": "open",
"mergeable_state": "unstable",
"repo_stars": 600,
"repo_forks": 240,
"updated_at": "2026-06-30T04:20:02Z",
"updated_age_days": 0,
"next_action": "review gate",
"checks": {"state": "unknown", "failed_check_runs": [], "pending_check_runs": []},
},
],
}

output = module.format_integration_markdown(metrics)

active_queue = output.split("## Active operator queue", 1)[1].split("## Manual handoff gates", 1)[0]
manual_gates = output.split("## Manual handoff gates", 1)[1].split("## Manual review gates", 1)[0]
Comment on lines +1108 to +1109

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The current assertion logic is fragile because it assumes that the ## Manual review gates section will always be present in the output. If we filter out manual handoff integrations from the review gates section (to fix the duplication issue), the ## Manual review gates section will not be rendered in this test, causing an IndexError on the split.

We should make the section extraction more robust by checking for the presence of subsequent headers before splitting.

    active_queue = output.split("## Active operator queue", 1)[1].split("## Manual handoff gates", 1)[0]
    manual_gates = output.split("## Manual handoff gates", 1)[1]
    for header in ["## Manual review gates", "## Failed or pending checks"]:
        if header in manual_gates:
            manual_gates = manual_gates.split(header, 1)[0]
            break

assert "punkpeye/awesome-mcp-servers#7153" not in active_queue
assert (
"- [punkpeye/awesome-mcp-servers#7153](https://github.com/punkpeye/awesome-mcp-servers/pull/7153): "
"submit Glama; Glama listing and score badge required before review"
) in manual_gates
assert "huggingface/optimum-intel#1801" not in manual_gates


def test_format_integration_markdown_lists_known_review_gates():
module = load_growth_metrics_module()
metrics = {
Expand Down