Maintain exhaustive Slate/Plate issue-closure ledgers from current issue, PR, test and local proof evidence.
72%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
Low
Low-risk findings worth noting
Fix and improve this skill with Tessl
tessl review fix ./.agents/skills/issue-harvester/SKILL.mdHandle $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 allThe skill expands that into the full issue-by-issue loop. Do not make the user paste the long closure-ledger prompt again.
This skill works for:
--state all;Derive repo_key like this:
owner/repo -> repo../repo or /path/to/repo -> basenamedocs/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/*.jsonThe 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:
If no ledger exists:
research harvest;state=all unless explicitly narrowed;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 10000If 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,closedAtLive GitHub is final truth for current state, comments, linked PRs, and closure links when the local archive is stale or incomplete.
--refresh-onlyUse --refresh-only when another workflow needs current issue inventory without
starting the unchecked issue loop.
unchecked.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.
For every relevant closed issue, inspect whether a linked PR added a test before deciding local coverage.
Look for:
Fixes #, Closes #, Resolves #, issue URLs, and maintainer references;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.
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_actionExisting 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-v2plateexternal-frameworkdocs-support-releaseneeds-planunknownstatus values:
uncheckedinvalid-skipcovered-by-existing-testtest-writtenplate-owned-covereddeferred-with-ownerneeds-reproblockedProcess issues in ascending issue number order unless the user gives a different objective. For each unchecked row:
invalid-skip with a concrete
reason and continue. When current behavior is uncertain, mark needs-repro
instead of designing a fix.--slate-v2-only
to defer Plate rows instead of patching Plate.AGENTS.md. When a type,
lint rule or existing test already catches it, record that owner instead.docs/editor-issue-harvester/<repo_key>/full/issue-closure-overrides.json.issue-closure-ledger.tsv and .md in the same docs directory.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 the Triage playbook for a udecode/plate issue; only the
coordinator hands the normalized local repair packet to pstack's Bug fix playbook.
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:
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 v2 only, do not write Plate tests; mark
deferred-with-owner with the concrete Plate owner and reason.
After each issue, or each batch of ten trivial skip/covered issues:
docs/editor-issue-harvester/<repo_key>/full/issue-closure-overrides.json;issue-closure-run.md;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.
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.
udecode/plate
f0c616a
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.