# Batch Filing Gaps

> Batch scan canvases for GAP sections, deduplicate, route to correct repos, draft issue bodies, and file confirmed issues.

- Skill: `majiayu000/batch-filing-gaps` (Agent Skill, multi-file: 2 files)
- Install (CLI): `npx skillmds add majiayu000/batch-filing-gaps`
- Raw SKILL.md: https://api.skillmd.com/api/skills/majiayu000/batch-filing-gaps/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Productivity
- Author: majiayu000 (https://skillmd.com/u/majiayu000)
- Updated: 2026-09-09
- Page: https://skillmd.com/skills/majiayu000/batch-filing-gaps

---


# Batch Filing Gaps

Scan all observer canvases for `### GAP-*` sections, deduplicate similar gaps across users, route to the correct repo (`score-api` or `midi-interface`), draft issue bodies with user quotes as evidence, present for operator confirmation, and file approved issues via `gh issue create`.

---

## Core Principle

**Gaps are user-grounded.** Every issue filed must trace back to at least one direct user quote or feedback entry. No speculative issues.

---

## Triggers

```
/gap-to-issues                                # Scan all canvases
/gap-to-issues --canvas <username>            # Single canvas only
/gap-to-issues --repo score-api               # Filter to score-api issues only
/gap-to-issues --repo midi-interface          # Filter to midi-interface issues only
/gap-to-issues --dry-run                      # Preview without filing
```

---

## When to Use

- After a `/daily-synthesis` run that detected new gaps
- When 3+ canvases exist and cross-user patterns are visible
- Before sprint planning — to populate the backlog with user-grounded issues
- Periodically to ensure no gaps are accumulating unfiled

---

## Workflow

### Step 1: Scan Canvases

Glob `grimoires/observer/canvas/*.md` and grep for `### GAP-` sections.

For each GAP found, extract:
- GAP ID (e.g., `GAP-DATA-001`)
- Type: ACCURACY, WEIGHTINGS, UX, FEATURE
- Severity: HIGH, MEDIUM, LOW
- Status: IDENTIFIED, FILED, RESOLVED
- Source user and canvas
- Supporting quotes

**Skip** gaps with status `FILED` or `RESOLVED`.

### Step 2: Deduplicate

Group similar gaps across canvases:
- Same GAP type + similar description → merge into single issue
- Track all contributing users as evidence sources
- Use the highest severity across duplicates

Example: "Data staleness" appearing in 3 canvases → single issue with 3 user citations.

### Step 2.5: Source Fidelity Classification

Before routing or filing any gap, classify its evidence to prevent filing inferred features as concrete requests.

**4-Category Evidence Taxonomy:**

| Category | Criteria | Filing Action |
|----------|----------|---------------|
| **(a) User-reported bug** | Direct quote describes broken behavior | File as issue |
| **(b) User-expressed need** | Quote contains explicit request ("I wish...", "Would like to see...") | File as issue |
| **(c) Observed behavioral gap** | User behavior implies X but no explicit quote requesting it | File with `observed-pattern` label |
| **(d) Inferred feature** | Extrapolated from user vision/sentiment — no direct quote supports it | **BLOCK — do not file** |

**Gate Logic:**

1. For each IDENTIFIED gap, locate the supporting quote in the source canvas
2. Verify the quote **directly** supports the issue — no interpretation required
3. Category (d) gaps: remove from the filing batch, output warning, log to NOTES.md
4. Category (c) gaps: keep in batch but add `observed-pattern` to labels

**Apply this gate per-gap before proceeding to Step 3.**

---

### Step 3: Route to Repos

| GAP Type | Target Repo |
|----------|-------------|
| ACCURACY | `0xHoneyJar/score-api` |
| WEIGHTINGS | `0xHoneyJar/score-api` |
| UX | `0xHoneyJar/midi-interface` |
| FEATURE | `0xHoneyJar/midi-interface` |

### Step 4: Draft Issue Bodies

For each deduplicated gap, draft a GitHub issue:

```markdown
## User Feedback Gap

**Gap Type**: {ACCURACY|WEIGHTINGS|UX|FEATURE}
**Severity**: {HIGH|MEDIUM|LOW}
**Users Affected**: {N} ({usernames})

### Evidence

> "{direct user quote}" — @{username} (Rank #{rank}, {crowd_tier})

> "{another quote}" — @{username2} (Rank #{rank}, {crowd_tier})

### Context

{Description of the gap, what users expected vs what happened}

### Score API Position of Reporters

| User | Rank | Tier | Signal Weight |
|------|------|------|---------------|
| {username} | #{rank} | {crowd_tier}/{elite_tier} | HIGH |

---

*Filed from observer gap analysis — grimoires/observer/canvas/{canvas}.md*
*Generated by /gap-to-issues*
```

**Labels**: `feedback`, `{gap_type}` (e.g., `data-accuracy`, `calibration`, `ux`)

### Step 4.5: Enrich with Visual Evidence

For each deduplicated gap, scan the MER timeline for snapshots of affected wallets:

```bash
# For each affected wallet in the gap
for wallet_alias in "${affected_wallets[@]}"; do
    mer_files=$(grep -rl "wallet_alias: $wallet_alias" grimoires/observer/timeline/MER-*.md 2>/dev/null || true)
    if [[ -n "$mer_files" ]]; then
        # Use most recent MER (last in sorted list)
        latest_mer=$(echo "$mer_files" | sort | tail -1)
        # Extract screenshot_url and score position from frontmatter/Data State
    fi
done
```

If MER(s) found for any affected wallet, append to the issue body (after Evidence, before footer):

```markdown
### Visual Evidence

| User | MER | Screenshot | Rank | Tier |
|------|-----|------------|------|------|
| {username} | [[timeline/{mer_id}]] | ![snapshot]({screenshot_url}) | #{rank} | {crowd_tier} |
| {username2} | [[timeline/{mer_id2}]] | (data-only) | #{rank2} | {crowd_tier2} |
```

For wallets with screenshots, embed the image inline. For data-only MERs, show "(data-only)" in the screenshot column. For wallets with no MER at all, omit the row.

If no MERs exist for any affected wallet, skip this section entirely — the issue uses text-only evidence (existing behavior).

**Score Position at Capture** table (one per wallet with a MER):

```markdown
### Score Position at Capture

| User | Combined | OG | NFT | Onchain | Crowd Tier | Elite Tier |
|------|----------|----|-----|---------|------------|------------|
| {username} | {combined} | {og} | {nft} | {onchain} | {crowd_tier} | {elite_tier} |
```

### Step 5: Present Batch Summary

Display all drafted issues to operator for confirmation:

```
Gap Issues Ready to File:

  1. [score-api] Data staleness in NFT holdings (HIGH)
     Evidence: 3 users (xabbu, elcapitan, ncs)
     → File? [Y/n]

  2. [midi-interface] Badge checklist missing earned indicators (MEDIUM)
     Evidence: 1 user (xabbu)
     → File? [Y/n]

  3. [score-api] Trust filter threshold unclear (LOW)
     Evidence: 1 user (juri23)
     → File? [Y/n]
```

**In `--dry-run` mode**: Show drafts without the confirmation prompt.

### Step 6: File Confirmed Issues

For each confirmed issue:

```bash
gh issue create --repo 0xHoneyJar/{repo} \
  --title "{title}" \
  --body "{body}" \
  --label "feedback,{type_label}"
```

Capture the issue URL from output.

### Step 7: Update Canvas GAP Status

For each filed gap, update the canvas:
- Change status from `IDENTIFIED` to `FILED`
- Add issue link: `Issue: {url}`
- Add filed date

---

## Error Handling

| Error | Resolution |
|-------|------------|
| No canvases found | Report "No canvases to scan" |
| No GAP sections found | Report "No unfiled gaps detected" |
| `gh` CLI not authenticated | Error with `gh auth login` instruction |
| Issue creation fails | Log error, continue with remaining issues |
| Canvas write fails | Log warning, issue is still filed |

---

## Validation

- [ ] Only scans IDENTIFIED gaps (skips FILED/RESOLVED)
- [ ] Deduplication groups similar gaps correctly
- [ ] Each issue has at least one direct user quote
- [ ] Correct repo routing (ACCURACY/WEIGHTINGS → score-api)
- [ ] Labels applied correctly
- [ ] Canvas GAP status updated after filing
- [ ] `--dry-run` creates no issues

---

## Related

- `/analyze-gap` — Single canvas gap analysis
- `/file-gap` — Single gap filing (this skill batches across canvases)
- `/daily-synthesis` — Detects gaps from UI feedback

