SuperAPI AI Directory

issue-harvester

Testing & quality

View repository

Updated 10-24 23:36

About this skill

Issue Harvester

Handle $ARGUMENTS.

Use this skill when the user wants exhaustive issue-history coverage, including closed issues that predate AI-written tests. The prompt should be small:

issue-harvester prosemirror
issue-harvester facebook/lexical --state all

The skill expands that into the full issue-by-issue loop. Do not make the user paste the long closure-ledger prompt again.

Scope

This skill works for:

  • Slate/Plate issue history;
  • external editor issue history such as Lexical, ProseMirror, CodeMirror, Tiptap, Monaco, and Quill;
  • open and closed issues, defaulting to --state all;
  • resuming an existing closure ledger;
  • adding only missing local tests for unchecked relevant issues.

Ledger Autodiscovery

Derive repo_key like this:

  • owner/repo -> repo
  • ../repo or /path/to/repo -> basename
  • direct ledger path -> parse the parent repo folder under docs/editor-issue-harvester/<repo_key>/

Default artifacts:

docs/editor-issue-harvester/<repo_key>/full/issues.md
docs/editor-issue-harvester/<repo_key>/full/issue-closure-ledger.tsv
docs/editor-issue-harvester/<repo_key>/full/issue-closure-ledger.md
docs/editor-issue-harvester/<repo_key>/full/issue-closure-overrides.json
docs/editor-issue-harvester/<repo_key>/full/issue-closure-run.md
.tmp/editor-issue-harvester/<repo_key>/raw/issues.json
.tmp/editor-issue-harvester/<repo_key>/raw/issues-all-with-bodies.json
.tmp/editor-issue-harvester/<repo_key>/raw/issue-bodies/*.json

The docs/editor-issue-harvester/<repo_key>/full/ directory is the canonical resume/checkmark workspace. It may contain compact generated TSV/Markdown/JSON state, but it must not contain raw issue bodies/comments. The .tmp path is raw cache only.

Do not broad-search docs/editor-issue-harvester/** or raw issue JSON just to learn ledger status. Parse issue-closure-ledger.md / .tsv directly for the check column, unchecked relevant, total rows, and next unchecked issue.

A file that declares itself generated stays generated: manual decisions go in issue-closure-overrides.json, never as new columns in the generated ledger. A frozen corpus is named a historical seed, not current state. A ledger family that mixes generated input, manual classification and a summary gets a local check that fails when they drift.

If a ledger exists:

  1. read the TSV/MD and overrides;
  2. preserve all checked/manual decisions;
  3. refresh issue inventory to the latest available state;
  4. add new issue numbers as unchecked rows;
  5. remove no historical rows unless the user explicitly asks;
  6. resume from the lowest unchecked issue number that matches the objective.

If no ledger exists:

  1. run the target repo/license gate from research harvest;
  2. inventory issues with state=all unless explicitly narrowed;
  3. cluster first;
  4. build the coverage matrix;
  5. generate the first closure ledger;
  6. start issue-by-issue processing from the first unchecked relevant row.

Refresh Commands

Prefer gitcrawl for archive input; gitcrawl holds its install and archive commands:

gitcrawl doctor --json
gitcrawl status --json
gitcrawl sync <owner/repo> --state all --json
gitcrawl search issues "" -R <owner/repo> --state all --json number,title,state,url,labels,updatedAt --limit 10000

If gitcrawl cannot provide the corpus, use gh search issues, the best local archive, or existing scratch issues. Record the fallback, state coverage, limit, and freshness. Do not call a sampled or capped corpus comprehensive. Write raw refresh output to .tmp/editor-issue-harvester/<repo_key>/raw/. Write only compact issue indexes, coverage rows, and checkmark ledgers to docs/editor-issue-harvester/<repo_key>/.

Use exact hydration before issue decisions:

gitcrawl sync <owner/repo> --numbers <issue-or-pr-ref> --with pr-details --json
gitcrawl threads <owner/repo> --numbers <issue-or-pr-ref> --include-closed --json
gh issue view <issue-number> --repo <owner/repo> --comments --json number,title,state,body,comments,labels,url,closedAt

Live GitHub is final truth for current state, comments, linked PRs, and closure links when the local archive is stale or incomplete.

--refresh-only

Use --refresh-only when another workflow needs current issue inventory without starting the unchecked issue loop.

  1. Discover or create the canonical ledger.
  2. Refresh all-state issue metadata through the normal provider/fallback.
  3. Preserve checked/manual decisions.
  4. Add new issue numbers as unchecked.
  5. Mark materially changed issue metadata for later re-read without erasing the existing decision.
  6. Regenerate compact issue indexes and closure ledgers.
  7. Record refresh time, provider, state coverage, limits, added count, changed count, and remaining unchecked count.
  8. Stop before issue hydration, PR/test provenance, local test creation, or runtime changes.

Raw issue bodies and comments remain under .tmp. The refresh is complete only when compact docs artifacts are current or the exact provider blocker is recorded.

Closed-Issue PR/Test Provenance

For every relevant closed issue, inspect whether a linked PR added a test before deciding local coverage.

Look for:

  • issue body links, timeline/crossrefs, and comments mentioning PRs;
  • Fixes #, Closes #, Resolves #, issue URLs, and maintainer references;
  • PR files touched;
  • PR test files changed;
  • upstream test names or behavior labels;
  • current Slate / Plate tests that already cover the same behavior.

Useful probes:

gh search prs "<owner/repo>#<issue-number>" --repo <owner/repo> --state all --json number,title,state,url,mergedAt
gh search prs "Fixes #<issue-number> OR Closes #<issue-number> OR Resolves #<issue-number>" --repo <owner/repo> --state all --json number,title,state,url,mergedAt
gh pr view <pr-number> --repo <owner/repo> --json number,title,state,body,files,commits,url,mergedAt
gh pr diff <pr-number> --repo <owner/repo> --name-only
rg -n "#<issue-number>|issues/<issue-number>|Fixes .*<issue-number>|Closes .*<issue-number>|Resolves .*<issue-number>" <target-repo>

For external repos, PR diffs and upstream tests are provenance only. Copy the behavior, not the code.

Row Schema

Each ledger row should carry enough information to resume without chat history:

issue_number
state
title
classification
owner
status
reason
linked_prs
upstream_test_provenance
local_coverage
local_test
verification_command
last_checked_at
next_action

Existing ledgers keep their own headers, so parse by header name, never by column position. Three header families exist: lexical and prosemirror (check, issue, state, relevant, closureKind, disposition, …), prosekit and wordgard (check, issue, state, relevant, classification, owner, status, …), and slate (issue_number, number, kind, state, …, with no check column). New ledgers use the schema above.

owner values:

  • slate
  • plate
  • external-framework
  • docs-support-release
  • needs-plan
  • unknown

status values:

  • unchecked
  • invalid-skip
  • covered-by-existing-test
  • test-written
  • plate-owned-covered
  • deferred-with-owner
  • needs-repro
  • blocked

Issue Loop

Process issues in ascending issue number order unless the user gives a different objective. For each unchecked row:

  1. Read title, body, comments, labels, state, existing classification, and current ledger row.
  2. Decide skip vs relevant. If irrelevant, write invalid-skip with a concrete reason and continue. When current behavior is uncertain, mark needs-repro instead of designing a fix.
  3. For closed relevant issues, scan linked PR/test provenance before coverage search.
  4. Classify owner: raw Slate, Plate, external-framework noise, docs/support, or needs-plan.
  5. Search exact current Slate and/or Plate coverage. Use --slate-only to defer Plate rows instead of patching Plate.
  6. If exact coverage exists, link file:line, test name, and focused command; run that command before marking covered.
  7. If coverage is absent, name the defect the issue describes and write the smallest local regression, contract, or browser test in the owner surface that fails for that defect, per the Tests rule in AGENTS.md. When a type, lint rule or existing test already catches it, record that owner instead.
  8. For external sources, express the test fresh from the invariant. Do not preserve upstream fixture/helper shape.
  9. Run focused verification.
  10. Update docs/editor-issue-harvester/<repo_key>/full/issue-closure-overrides.json.
  11. Regenerate issue-closure-ledger.tsv and .md in the same docs directory.
  12. Move to the next unchecked issue.

Do not patch runtime just because an external issue exists. Patch runtime only after a local failing proof exists or the missing test proves a current behavior contract gap. Return that issue-bearing candidate to maintainer slate-issue for one public Slate issue or maintainer for any other public issue; only the coordinator hands the normalized local repair packet to pstack's Bug fix playbook.

Coverage Search

Search for exact local coverage before writing a test:

rg -n "<distinct behavior phrase>|<issue number>|<upstream test label>" packages apps docs content benchmarks
rg --files packages apps docs content benchmarks | rg '(test|spec|playwright|integration|fixtures)'

Coverage is exact only when it proves the same behavior class, not merely the same feature area. Link:

  • file path and line;
  • test name;
  • verification command;
  • result of the focused command.

If coverage is partial, either strengthen the existing test or write a narrow new row. Avoid duplicate tests.

For Plate-owned rows, use the relevant Plate package/example command. If the run is scoped to Slate only, do not write Plate tests; mark deferred-with-owner with the concrete Plate owner and reason.

Regeneration

After each issue, or each batch of ten trivial skip/covered issues:

  1. update docs/editor-issue-harvester/<repo_key>/full/issue-closure-overrides.json;
  2. regenerate TSV and Markdown ledgers in that same docs directory;
  3. record issues checked, commands run, tests written, and next issue number in the active plan or issue-closure-run.md;
  4. keep going unless a stop rule fires.

If no generator script exists, update the TSV/MD by the smallest reliable local method and record that the generator is missing as a workflow gap.

Stop and hand off

Every relevant issue ends with a checkmark: an existing local test linked and verified, a new test written and verified, Plate-owned proof linked, or deferred-with-owner naming its owner and the condition that ends the deferral. Stop only when every relevant row for the objective is checked, a real blocker prevents all progress, a broad API or runtime decision belongs to best-api or the Plan playbook, or the timebox expires with the active packet decided. Never stop after a cluster summary, a first matrix or the first ten rows unless a sample was asked for.