
Skill
magpie-security-tracker-stats-dashboard
generate security tracker statistics dashboard
Description
Generate a self-contained HTML dashboard of `<tracker>` repository statistics for security-team review.
SKILL.md
security-tracker-stats-dashboard
Read-only skill that renders a self-contained HTML page summarising
the state of <tracker> over time. The skill wraps the
tools/security-tracker-stats-dashboard/
runtime tool — both the slash-command path (this skill) and the
script path (run.sh) run the same fetch + render pipeline; the
skill adds invocation niceties (resolving cache paths, surfacing the
output URL, proposing a stale-cache refresh) but never mutates
anything.
The skill is read-only on GitHub — it does not create or modify
issues, comments, labels, or PRs. It only fetches data via gh and
renders an HTML file.
Adopter overrides
Before running the default behaviour documented
below, this skill consults
.apache-magpie-local/security-tracker-stats-dashboard.md (personal, gitignored) and .apache-magpie-overrides/security-tracker-stats-dashboard.md (committed, project-wide)
in the adopter repo if it exists, and applies any
agent-readable overrides it finds. See
docs/setup/agentic-overrides.md
for the contract — what overrides may contain, hard
rules, the reconciliation flow on framework upgrade,
upstreaming guidance.
Configuration for the renderer (bucket granularity, milestones,
categories, scope labels, triage keywords, …) lives in a separate
YAML file the adopter places at
.apache-magpie-overrides/security-tracker-stats.yaml (path is
adopter-configurable via tracker_stats_config: in
<project-config>/security-tracker-stats.md).
The agentic override file above is reserved for behavioural
overrides of this skill (when to propose a refresh, where to write
the HTML, etc.); renderer knobs go in the YAML config.
Hard rule: agents NEVER modify the snapshot under
<adopter-repo>/.apache-magpie/. Local modifications
go in the override file. Framework changes go via PR
to apache/magpie.
Snapshot drift
Also at the top of every run, this skill compares the
gitignored .apache-magpie.local.lock (per-machine
fetch) against the committed .apache-magpie.lock
(the project pin). On mismatch the skill surfaces the
gap and proposes
/magpie-setup upgrade.
The proposal is non-blocking — the user may defer if
they want to run with the local snapshot for now. See
docs/setup/install-recipes.md § Subsequent runs and drift detection
for the full flow.
Drift severity:
- method or URL differ -> ✗ full re-install needed.
- ref differs (project bumped tag, or
git-branchlocal is behind upstream tip) -> ⚠ sync needed. svn-zipSHA-512 mismatches the committed anchor -> ✗ security-flagged; investigate before upgrading.
Prerequisites
ghauthenticated with read access to<tracker>(and to<upstream>for PR metadata, when configured).python3(3.9+).jq(used byfetch_events.pyvia gh's--jqflag).- Network access to
api.github.comand (for viewing the output HTML) Plotly's CDN. - Optional: PyYAML. When missing, the renderer falls back to a
bundled minimal YAML subset parser sufficient for
default-config.yamland typical overlays.
Inputs
The skill accepts up to three optional arguments:
| Selector | Meaning |
|---|---|
| (no args) | render with all defaults — monthly buckets, default categories, the adopter's milestones |
quarterly / monthly | override the bucket granularity |
<output-path> | write the HTML to a specific path |
clear-cache | delete the fetch cache before fetching |
since:YYYY-MM / since:YYYY-Qn | override the start bucket |
If the adopter passes nothing, surface the resolved output path and cache state up front so they can interrupt before a 5-10 minute fetch.
How to invoke
- Resolve config. Read
<project-config>/security-tracker-stats.mdfor the project's per-renderer YAML config path (default:<adopter-repo>/.apache-magpie-overrides/security-tracker-stats.yaml). Surface to the user which config file will be applied and what bucket granularity it resolves to. If the YAML file does not exist, fall back silently to the framework'sdefault-config.yaml. - Check cache freshness. Inspect
${TRACKER_STATS_CACHE:-/tmp/tracker-stats-cache}/issues.jsonmtime. If older than 24 h, propose a fresh fetch; if missing or the user passedclear-cache, do a fresh fetch unconditionally. - Run the orchestrator. Substitute placeholders and invoke:
TRACKER_STATS_REPO=<tracker> \ TRACKER_STATS_UPSTREAM_REPO=<upstream> \ TRACKER_STATS_CONFIG=<adopter-repo>/.apache-magpie-overrides/security-tracker-stats.yaml \ bash <framework>/tools/security-tracker-stats-dashboard/run.sh <output-path>
When the user passedmonthly/quarterlyorsince:<start>, prepend the matchingTRACKER_STATS_BUCKETS=/TRACKER_STATS_START=env vars. - Report the result. Print the final HTML path and a short
summary (total trackers, open count, latest-bucket category
breakdown, triage-median, PR-merge-median when configured). The
pipeline already echoes most of this to stdout — pass it
through verbatim and add the clickable
file://<output-path>line at the end.
The full pipeline:
fetch_issues.py—gh issue list --state all --limit 1000-><cache>/issues.json.fetch_roster.py—gh api repos/<tracker>/collaborators-><cache>/roster.txt.fetch_bodies.py— per-issuebody+closedByPullRequestsReferences-><cache>/issue_extra.json.fetch_events.py— per-issue label-history events -><cache>/events/<N>.json.fetch_prs.py— per-PRcreatedAt/mergedAt/statefrom<upstream>-><cache>/prs.json. Silent no-op whenTRACKER_STATS_UPSTREAM_REPOis empty ornone.render.py— reads cache + config, writes HTML to$TRACKER_STATS_OUT.
Each fetch script resumes from cache, so re-running after a partial failure (rate limit, transient HTTP error) only re-fetches what is missing.
Configuration overview
See
tools/security-tracker-stats-dashboard/default-config.yaml
for the schema with inline documentation, and
tools/security-tracker-stats-dashboard/README.md
for the load order, predicate keys, and snapshot replay semantics.
The most-overridden knobs by adopters tend to be:
buckets:— monthly vs. quarterly. Smaller tracker repos (<50 issues / year) read better at quarterly granularity.milestones:— vertical annotations marking process changes the dashboard should highlight (skill adoption, team handover, policy update). Set to[]to remove them.scope_labels:— the project's primary "what does this affect" axis. Resolved fromscope_detection.labelsin<project-config>/project.md(and the matching rows of<project-config>/scope-labels.md). The framework default is[<scope-a>, <scope-b>, <scope-c>]— adopters re-state this list in their overlay to match their own scope set.categories:— the lifecycle-band classification rules. Defaults match the framework's reference implementation byte-for-byte; adopters with different label conventions (e.g.triagedinstead of noneeds triage) re-state the whole list. The label literals used in predicates come fromtracker.labelsin<project-config>/project.md.triage.keywords:/triage.bot_prefixes:— the time-to-triage signal. Adopters whose security team uses different phrasing in triage-proposal comments override these.
Hard rules
Golden rule 1 — read only, never write. The skill must not post comments, add labels, close, edit, or otherwise mutate any tracker, PR, or upstream resource. If the user asks for stats and also wants an action, decline the mutation.
Golden rule 2 — proposal-before-fetch on stale cache. Before
running a fresh full fetch (which costs ~5-10 minutes of gh API
calls), surface the proposal and wait for explicit user
confirmation. Incremental re-renders against a warm cache (~30
seconds) can run without a prompt.
Golden rule 3 — never edit the snapshot. As with every other
skill, agentic overrides go in
.apache-magpie-overrides/security-tracker-stats-dashboard.md; renderer
overrides go in the project's tracker-stats YAML config file. The
gitignored snapshot under .apache-magpie/ is never modified.
Golden rule 4 — surface the config path on every run. The dashboard's output depends entirely on which YAML file the renderer loaded. Print the resolved config path (or "default") as the first line of skill output so the user can tell at a glance whether their overlay is being picked up.
Failure modes
| Symptom | Cause | Fix |
|---|---|---|
events/<N>.json missing for some N | gh transient failure during paginate | Re-run; fetch_events.py resumes from cache |
prs.json has {"error": ...} entries | False-positive body parse (PR# doesn't exist) | Silently filtered at render; safe to ignore |
c_rel median jumps after re-fetch | New advisory shipped since last run | Expected — re-render is correct |
Empty c_prc / c_prm / c_rel early buckets | No linked PR in those tracker buckets | Expected — not all early trackers had a fix PR |
| Three PR charts missing entirely | upstream_repo: null in config (or env override) | By design — set upstream_repo: if you want them |
ModuleNotFoundError: yaml | PyYAML missing | Bundled fallback parser handles default-config.yaml; install pyyaml for richer overlays |
More skills from the magpie repository
View all 71 skillsgenerate-cve-json
generate CVE JSON documents
Jul 12ComplianceSecurityTechnical Writingmagpie-audit-finding-fix
fix findings from code audit tools
Jul 12AuditCode AnalysisDebuggingmagpie-ci-runner-audit
audit GitHub Actions workflow runner compatibility
Jul 12AuditCI/CDGitHub Actionsmagpie-committer-onboarding
onboard Apache project committers
Jul 12ManagementOperationsProcess Documentationmagpie-contributor-activity-sweep
generate contributor activity reports
Jul 12AnalyticsGitHubReportingmagpie-contributor-nomination
generate contributor nomination briefs
Jul 12EngineeringGitHubReporting
More from Apache Software Foundation
View publisherdatafusion-python
write Apache DataFusion Python code
datafusion-python
Jul 12Data AnalysisPythonSQLpixiu-filter-author
create custom filters for Dubbo gateway
dubbo-go-pixiu
Jul 12API DevelopmentEngineeringGopixiu-http-to-dubbo
map REST endpoints to Dubbo services
dubbo-go-pixiu
Jul 12API DevelopmentGoREST APIpixiu-llm-gateway
configure Apache dubbo-go-pixiu as AI gateway
dubbo-go-pixiu
Jul 12API DevelopmentClaude APIGeminiLLM +1pixiu-mcp-integration
configure dubbo-go-pixiu as MCP gateway
dubbo-go-pixiu
Jul 12API DevelopmentAuthGoMCPbydbql
generate and execute BanyanDB BydbQL queries
skywalking-banyandb
Jul 12AnalyticsDatabaseSQL