live1,247 agents deployed
← All skillsSign up to install

Skill Gap

General↓ 0 installsUpdated 105d ago
Curatedaaronjmars

Cross-fork skill adoption digest — per-fork table of upstream skills the fork hasn't enabled, top forks by gap size called out, silent when gaps are small

SKILL.md preview

---
name: Skill Gap
description: Cross-fork skill adoption digest — per-fork table of upstream skills the fork hasn't enabled, top forks by gap size called out, silent when gaps are small
var: ""
tags: [meta, community]
---
> **${var}** — Optional. Pass `dry-run` to skip notify (state and article still write). Pass `owner/repo` to override the parent repo. Combine with a space (`dry-run owner/repo`) for both.

Today is ${today}. Three fork-intelligence skills already exist: `fork-cohort` answers *is the fork alive?* (workflow runs in 7d), `fork-release` answers *has any fork shipped a versioned artifact?*, `contributor-spotlight` answers *who's pushing the most code?* None of them answer the obvious operator question: **"what's in upstream that I haven't adopted yet?"** This skill closes that layer.

## Why this exists

A fork that activates the agent on day one and never re-syncs accumulates an invisible drift — upstream keeps shipping skills, the fork stays at its activation-day skill count, and the operator has no surface that flags the gap. Skill drift is silent. The first sign is usually a fork operator noticing six months later that everyone else's agent is doing something theirs isn't.

The gap also tells upstream something: which new skills are getting picked up by the fleet, and which are launching into silence. A skill that ships and is never adopted by any fork in 8 weeks is a skill worth re-examining.

## Scope and inputs

Reads from two places, with graceful degradation if either is missing:

1. **`memory/topics/fork-cohort-state.json`** (optional accelerator) — gives the POWER + ACTIVE fork list, classification, and `enabled_count`. When present, this skill targets only POWER + ACTIVE forks (the audience that actually cares about gaps — STALE/COLD forks aren't running anything anyway).
2. **`gh api repos/{parent}/forks`** (always called as fallback / first run) — when fork-cohort state is absent, missing the forks list, or older than 8 days, this skill builds its own POWER + ACTIVE list from scratch using the same activation rule (≥1 workflow run in last 7d).

The intent is: when fork-cohort is enabled and runs Sunday 19:00, skill-gap at 21:00 reuses its work. When fork-cohort hasn't been enabled yet, skill-gap still works, it's just slower.

## Steps

### 0. Bootstrap

```bash
mkdir -p memory/topics articles
[ -f memory/topics/skill-gap-state.json ] || cat > memory/topics/skill-gap-state.json <<'EOF'
{"parent":null,"last_run":null,"last_status":null,"upstream_skill_count":null,"forks":{}}
EOF
```

`forks` is a map keyed by `owner/repo`. Each entry holds `{missing_count, missing_slugs (cap 50), top_missing_categories, last_seen, classification_source}`. Old entries (fork no longer in POWER+ACTIVE) are evicted on each run.

### 1. Parse var

- Split `${var}` on whitespace. Tokens: `dry-run`, anything matching `^[A-Za-z0-9_.-]+/[A-Za-z0-9_.-]+$` (treated as `PARENT_OVERRIDE`), anything else.
- If any unknown token is present → log `FORK_SKILL_GAP_BAD_VAR: ${var}` and exit (no notify).
- `MODE=dry-run` if `dry-run` token present, else `execute`.

### 2. Resolve parent repo

```bash
if [ -n "$PARENT_OVERRIDE" ]; then
  PARENT_REPO="$PARENT_OVERRIDE"
else
  PARENT_REPO=$(gh api "repos/$(gh repo view --json nameWithOwner -q .nameWithOwner)" --jq '.parent.full_name // .full_name')
fi
PARENT_OWNER="${PARENT_REPO%%/*}"
```

If `state.parent` is set and differs from the resolved `PARENT_REPO` → log `FORK_SKILL_GAP_PARENT_CHANGED`, reset `forks` to `{}`, update `state.parent`.

### 3. Read upstream skills.json (parent baseline)

```bash
gh api "repos/${PARENT_REPO}/contents/skills.json" \
  --jq '.content' 2>/dev/null | base64 -d > /tmp/fsg-upstream.json
UPSTREAM_SLUGS=$(jq -r '.skills[].slug' /tmp/fsg-upstream.json | sort -u)
UPSTREAM_COUNT=$(echo "$UPSTREAM_SLUGS" | wc -l | tr -d ' ')
```

Also pull a slug→category map for the missing-categories rollup:

```bash
jq -r '.skills[] | "\(.slug)\t\(.category // "other")"' /tmp

…