Skip to content
Back to skills

File Issue

ASecurity

Writes issue text and files it — resolve the team's writing

  • 3 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added November 7, 2026
ai-agentsrustgoshellbashtestinggitapi

Works with

  • api

Security analysis

A100/100

Scanned November 11, 2026

npx -y skills add buchbend/lore --skill file-issue --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of File Issue?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for File Issue
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/buchbend-file-issue/badge)](https://www.skillsdirectory.com/skills/buchbend-file-issue)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: lore:file-issue
description: Writes issue text and files it — resolve the team's writing
  rules, draft in their skeleton (single change, batch, a caller's template, or a PR
  body), lint with Vale when Vale is installed, then post with gh. Use whenever you are
  about to write or edit a GitHub issue, a sub-issue, or a PR description. Triggers on
  "file an issue", "file these as issues", or "/lore:file-issue".
---

# File Issue

Writes issue text and files it. Every workflow skill that writes an issue or a PR body
comes here to do it, and the user can invoke it directly.

**The caller decides *what* to capture. This skill owns *how* to write and file it.**
Never re-litigate the caller's judgement about whether something deserves an issue.

## Hard rule: run in-context

Do every step in the calling session. **Never spawn a subagent** — not to draft, not to
lint, not to post. One subagent per issue is the cost this skill exists to avoid.

## 1. Resolve the writing rules, the filing rules and the glossary

```bash
lore style show writing-rules
lore style show filing
```

`filing` names the home of each fact. `writing-rules` carries the required section skeleton, the
EARS patterns for acceptance criteria, and the prose rules. **Never write from memory of the
rules** — a team overrides the rules inside its wiki, so the resolved text is the only
authority. Add `--wiki <name>` when the target repo belongs to a wiki other than the cwd's.

Use the repo's domain terms, which its `CONTEXT.md` defines. Print the ones you use with `lore
glossary <term> [<term> …]` (`--cwd <checkout>` for another repo), and use no synonym. When the
repo holds no `CONTEXT.md`, draft without one and name the absence in one line of your report.
**Never write to `CONTEXT.md`** — a term worth adding belongs to `grilling`, not this
skill.

## 2. Draft to a file whose name ends in `.md`

Resolve the draft path once. `<slug>` is a short kebab-case slug of the title:

```bash
realpath -m "${TMPDIR:-/tmp}/lore-file-issue-<slug>.md"
```

Write the body to the printed absolute path: `<draft>` below. **Repeat that path
literally in steps 3 and 4. Never resolve it again or hold it in a shell variable** —
each step may run as its own shell, and `TMPDIR` differs between a sandboxed command
and an unsandboxed one. Vale would then lint nothing.

The slug keeps two sessions apart. With a fixed filename, a second session under the same
`TMPDIR` overwrites the draft, and the first session posts text it never wrote.

The `.md` extension is load-bearing. The Vale config scopes its rules to `[*.md]`, so a
draft saved as `.txt`, or with no extension, lints zero files and exits 0 — step 3 would
report a clean draft without having read one line of it.

Pick the mode from what the caller handed you:

| Mode | Use when | Shape |
|---|---|---|
| **Single change** | there is one change to capture | The writing rules' full section skeleton. One statement under "Required behaviour", with its own EARS criteria. |
| **Batch** | several changes share one Context, go into one PR, and have no ordering between them | Keep the skeleton. Give each change its own numbered subheading under "Required behaviour", then repeat the same numbered subheadings under "Acceptance criteria". **Every numbered change carries its own criteria** — never one pooled list. |
| **Caller template** | the caller supplied a structure (a sub-issue header, an epic-seed shape) | Keep the caller's structure exactly. Add no section, drop no section, reorder nothing. Apply the prose rules and EARS *inside* the supplied structure. |
| **PR body** | writing the body for `gh pr create` | Prose rules only. No issue skeleton. |

Before drafting a batch, check the "Batch issues" section for the split rule.
A change that needs its own Context, or that must merge before another change, is a
separate issue rather than a numbered block.

### When a fact is missing

Write the section heading and `TODO:` followed by the specific question. **Never fill
the gap with a plausible guess.** A confident sentence written over a missing fact is
the failure the writing rules exist to stop, and it survives review far too easily.

## 3. Lint — only when Vale is installed

Check for Vale first, as its own command. Keep the two commands separate — chaining
them with `&&` makes a missing Vale exit non-zero, which is indistinguishable from the
"findings" exit below, and sends you into a fix loop over a lint that never ran.

```bash
command -v vale
```

Empty output means Vale is absent. **Post the draft unlinted** and say so in one line
when you report back. The linter never blocks filing. (`lore setup` also reports
whether Vale is on PATH.)

With Vale present:

```bash
test -f "<draft>" || { echo "draft missing: <draft>"; exit 2; }
vale --config "$(lore style vale-config)" "<draft>"
```

Read the result by exit code, not by whether anything printed:

- **Exit 1** — at least one `error`-level finding: banned vocabulary, a sentence past the
  length ceiling, or a retired heading. Rewrite those, then run again until the exit code
  is 0. A retired heading means the structure you drafted from has moved — re-read the
  template rather than renaming the heading.
- **Exit 0 with findings printed** — `warning`-level heuristics only. Advisory.
- **Exit 2** — the invocation itself is broken, not the prose: the draft is missing, the
  path argument is empty, or Vale cannot resolve the `--config` path. **Stop and report
  the path.** Editing prose here rewrites a draft that was never read.

Vale reports "0 files" as success. When the output names `stdin` or "0 files", the lint
did not run. Confirm the output names your draft file before you trust a clean result.

The heuristics over-fire by design, and the writing rules say as much. The participle rule
matches any capitalised `-ing` word opening a sentence, so a heading like
`## Testing decisions`, or a sentence opening with `Nothing`, trips it. **Do not mangle
correct prose to silence a warning.** Leave the sentence and move on.

Cap the fix loop at three passes. A finding that survives three rewrites is a rule
fighting a correct sentence. Post the draft anyway and name the finding when you report
back.

## 4. Post the exact file you linted

```bash
gh label create agent-filed --repo <owner>/<repo> --color ededed \
  --description "opened by an agent" 2>/dev/null || true
gh issue create --repo <owner>/<repo> --title "<imperative title, max 12 words>" \
  --body-file "<draft>" --label agent-filed
```

Every issue this skill opens carries the `agent-filed` label. `gh label create` above
is a no-op once the label exists, so run it every time rather than checking first.

Use `--body-file`, never a retyped `--body` string — the bytes Vale checked must be the
bytes that get posted. For a PR body, swap in `gh pr create --body-file ...`. For a
comment, draft the file so it opens with a line naming yourself as agent-filed, then
post it with `gh issue comment <n> --body-file ...` or `gh pr comment <n> --body-file ...`.

Close only an issue you opened yourself (a dead end, closed as not planned with the reason in the
close comment); never change the state of a human's issue or PR.

In batch mode the caller chooses the granularity it asked for: one issue holding the
numbered blocks, or one issue per block. Do not silently split or merge what you were
given.

Report every URL you created back to the caller.

## Callers

[`orient`](../orient/SKILL.md), [`grilling`](../grilling/SKILL.md),
[`to-epic`](../to-epic/SKILL.md), [`build`](../build/SKILL.md) — its follow-ups, its PR
bodies and the PR bodies its teammates open — [`document`](../document/SKILL.md) and
[`handover`](../handover/SKILL.md) file through this skill instead of writing issue or PR
bodies inline.

Machine-readable text stays exempt: build-order tables, board comments, and reviewer
verdicts are parsed, not read, so the writing rules do not apply to them.

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

View all in ai-agents →

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.