work-items-to-issues — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited work-items-to-issues (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
bash "${CLAUDE_PLUGIN_ROOT}/scripts/han-config-dir.sh" 2>/dev/null || echo "$HOME/.claude"cat .han/config.md 2>/dev/null || echo ""As your first action, use the Read tool on .han/config.md inside the personal config directory path above. A read that returns no file is no personal configuration: continue silently. When that file or the project .han/config.md probe supplies content, apply it per config-rule.md, which governs precedence between the two files, relative-path resolution, and what to do with a file that reads but cannot be used.
Take an already-broken-down work-items.md file (produced by /plan-work-items) and publish each slice as a GitHub issue in its target repo.
The breakdown work — drafting slices, assigning symbolic IDs, specifying dependencies, inventorying references — has already been done upstream. This skill's job is to map each slice to its target repo, validate the format, write a per-repo work-items file alongside the source, and run the publish pipeline.
work-items.md —never as a native blocker link.
blocked_by relationships are within-repo only. A cross-repo Depends on is a format error to surface forrepair.
W-N for every slice) and per-repo prefixes (e.g., V2-N backend, W-N frontend, EV-N events). The publish scripts accept any uppercase prefix.
schema docs, runbooks, ADRs, coding standards. Issues that consume an HTTP endpoint or event payload MUST link the contract section that defines it.
ui-designs/ subfolder, MUST embed the relevant screenshots inline usingsame-target-repo raw URLs. See references/screenshot-embed-rules.md.
decision logs, review findings, team findings, facilitation summaries, gap analyses, and anything under an artifacts/ subfolder of the plan that is not a contract or design reference. Full include/exclude list in references/reference-artifact-inventory.md.
If the path is not provided, ask for it. The input is a single work-items.md produced by /plan-work-items. Read it.
If the user named a target repo (or repos), a label, or an assignee, note them for Steps 2 and 6. By default, issues are created with no label and no assignee — only apply a label or assignee when the user explicitly asked for one.
Determine which repo each slice belongs to. Use both signals and reconcile them:
work-items.md files include an intro paragraph naming which SYMsship to which repo (e.g., "W-1 through W-4 ship to acme-api. W-5 through W-9 ship to acme-web."). Parse this for the mapping.
**Work to be done.** and **References.** blocksreference files in the target repo. Path roots map cleanly: acme-api/... → acme/acme-api, acme-web/... → acme/acme-web, acme-events/... → acme/acme-events. Use this to verify the prose and to assign any slice the prose doesn't cover.
If the prose and the file-path evidence disagree for a slice, surface the conflict to the user before proceeding.
Check the work-items file against the format invariants in references/issue-template.md and references/work-items-file-format.md:
## <SYM-N> — <title> with an em-dash separator (already-publishedheadings annotated as ## <SYM-N> (#NNN) — <title> are valid too).
**Depends on.**, trailing period, None. or comma-separated SYMs.Depends on line maps to the same target repo as the dependent slice(under the map from Step 2).
https://github.com/<org>/<target-repo>/raw/<branch>/.github/issue-assets/<feature-slug>/<SYM-N>/<file>.<ext> against the target repo's default branch and a real file under <plan-folder>/ui-designs/, whose extension is one of the accepted set (png, jpg, jpeg, gif, webp, svg, pdf) and is copied into the URL unchanged. <feature-slug> is the kebab-cased basename of the plan folder.
standard, or other named artifact.
summaries, gap analyses, or anything under an artifacts/ subfolder that is not a contract or design reference.
When a check fails, attempt evidence-based repair. Pull evidence from the source work-items.md, the parent plan referenced in its intro, the feature spec in the same folder, sibling files in the plan folder, and the target repo's ADRs / coding standards / docs:
None. if no blockers are evident in the slice's prose. Cite the absence.file and replacing the line with None. or remaining within-repo SYMs. Cite the SYM→repo map entries that prove the cross-repo split.
plan's External Interfaces / API Contracts section. Cite the anchor.
files by inspecting the feature spec's Visual Reference table and the spec's inline screenshot embeds. Cite the spec section.
held) restating the decision in plain language, with a Plan decisions References bullet naming the ID plus a one-sentence description. Cite the include/exclude list.
After validation, report findings in plain language. For each finding, name:
Then give the user three actions:
work-items.md (so the per-repo split filesinherit them) and proceed to Step 4.
If validation passes with no findings, proceed silently to Step 4.
Present a table for user review:
| SYM | Title | Target repo |
|---|---|---|
| W-1 | Backend per-list validator generalization | acme/acme-api |
| W-2 | … | acme/acme-api |
| W-5 | Frontend type widening and drift comparator | acme/acme-web |
Wait for confirmation before writing files or creating issues.
For each target repo named in the SYM→repo map, write a <repo-name>.work-items.md file in the same folder as the source work-items.md. The per-repo file is a filtered view of the source — it is the file the publish scripts consume:
keeps each per-repo file self-contained for review.
apply to at least one slice in this repo. When in doubt, include the entry.
The source work-items.md is not modified by the publish step. The per-repo files are what carry the (#NNN) issue-number annotations after publishing.
For each per-repo file, publish it by running ${CLAUDE_SKILL_DIR}/scripts/publish-work-items.sh <per-repo-work-items-file> <org>/<target-repo> <plan-folder> [--label <name>] [--assignee <user>]. Pass the per-repo work-items file written in Step 5, the target repo as <org>/<target-repo>, and the plan folder that contains the ui-designs/ subfolder.
Created issues are unassigned and carry no label by default. Append --label <name> and/or --assignee <user> only when the user asked for a label or assignee (Step 1). Both flags are optional and may be omitted.
The wrapper runs three idempotent scripts in order:
.github/issue-assets/<feature-slug>/<SYM-N>/<file>.<ext> URLfrom the per-repo file and copies the matching file from <plan-folder>/ui-designs/ into the target repo, verifying each upload. The <feature-slug> segment (the kebab-cased plan-folder basename) keeps assets from different features that publish to the same repo from colliding. Upload is adaptive: by default each file is written directly to the default branch via the GitHub Contents API, but if that branch is protected and rejects the direct write (HTTP 409), the script falls back to committing the assets to an assets branch, opening a pull request, and printing the PR URL. The embedded image URLs always name the default branch, so on the PR path the inline designs render once that assets PR merges — the issues are still created immediately. Overwrites existing files cleanly and, on re-run, reuses the assets branch and open PR — but only a branch it created for this feature (one already carrying the feature's issue-assets/<feature-slug>/ tree); a same-named branch it does not own is refused rather than committed onto.
## <SYM-N> slice in file order (blocker-first),unassigned and unlabeled by default. When --label <name> is passed, it applies that label to every issue, creating it on the repo only if it does not already exist (an existing label's color and description are left intact); when --assignee <user> is passed, it assigns each issue to that user. Captures each returned issue number and rewrites the heading in place to ## <SYM-N> (#NNN) — <title>. Skips slices already annotated with (#NNN) so partial runs resume cleanly.
**Depends on.**line, and POSTs repos/<repo>/issues/<N>/dependencies/blocked_by once per blocker. Errors out if a blocker SYM is not present in the same file (cross-repo dependencies are forbidden as native links — they belong in the cross-repo work-order prose).
When upload-screenshots.sh reports that it fell back to PR mode (it prints a NOTE: with an assets-branch pull request URL), surface that PR URL to the user and tell them the issues' inline designs render only once that assets PR merges. This is a required follow-up action; do not summarize it away.
The format invariants the scripts depend on (heading shape, URL scheme, Depends on syntax) are documented in references/issue-template.md. Edits to that template require matching script changes.
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.