feat(issue): add comprehension axis and host-free reference grammar
Rule 4 now tests two axes — reachability (the pointer resolves) and comprehension (a linearly-reading human understands the entry without absorbing the target). A reachable-but-opaque reference no longer passes. References go host-free: absolute URLs with a server name or port are banned; the canonical clickable forms are Gitea relative links — src/commit/<sha>/path#user-content-<slug> for a file section/line and issues/N#issuecomment-M for a comment. Verified against live Gitea 1.26.2. Bind every author, not just an explicit invocation, and pull milestones into scope (rules 1/2/4 on the description; the title names the container). Propagate the comment-link form and the rule-4 rename to boss.
This commit is contained in:
+104
-38
@@ -1,6 +1,6 @@
|
||||
---
|
||||
name: issue
|
||||
description: Use when creating, editing, commenting on, or closing a Gitea issue — filing a bug, feature, or idea into the tracker, or turning a finding into a tracker item. Covers the issue-writing conventions and the tea-CLI mechanics for the operation.
|
||||
description: Use when creating, editing, commenting on, or closing a Gitea issue or milestone — filing a bug, feature, or idea into the tracker, or turning a finding into a tracker item. Binds every actor that creates or edits an issue or milestone, human or skill, not just an explicit invocation. Covers the issue-writing conventions and the tea-CLI mechanics for the operation.
|
||||
---
|
||||
|
||||
# issue — write and edit Gitea issues
|
||||
@@ -11,9 +11,10 @@ description: Use when creating, editing, commenting on, or closing a Gitea issue
|
||||
|
||||
An issue is a durable artefact in the forward-queue, read later by
|
||||
humans and by other agents — usually without the conversation that
|
||||
produced it. It must stand on its own. This skill unifies how issue
|
||||
text is written so every issue reads the same way, and records the
|
||||
`tea` mechanics for creating and editing them.
|
||||
produced it, and a human reads it linearly, holding only what is on the
|
||||
page. It must stand on its own. This skill unifies how issue text is
|
||||
written so every issue reads the same way, and records the `tea`
|
||||
mechanics for creating and editing them.
|
||||
|
||||
An issue states facts and clearly-flagged claims about a concern. It
|
||||
is not a chat message.
|
||||
@@ -25,15 +26,20 @@ is not a chat message.
|
||||
| "Open an issue for X" / "file a bug about Y" | Yes |
|
||||
| "Edit / re-label / comment on issue #N" | Yes |
|
||||
| "Close #N" (outside a `closes #N` commit) | Yes |
|
||||
| Create or edit a **milestone** (the container for a big chunk) | Yes |
|
||||
| Turning a finding or deferred work into a tracker item | Yes |
|
||||
| A note relevant only to the current conversation | No |
|
||||
|
||||
Other skills file issues through these same conventions — e.g.
|
||||
**This binds every author, not just an explicit invocation.** Any actor
|
||||
that creates or edits an issue or a milestone — a person at the keyboard or
|
||||
any skill or agent doing it as a side-effect — writes it to these
|
||||
conventions; there is no second, looser standard for tracker text written
|
||||
in passing. Other skills reach the tracker through them constantly:
|
||||
`brainstorm` parks a deferred spec as a backlog issue, `audit` files
|
||||
regressions, and `boss` files skill-system deficiencies against the
|
||||
plugin's own tracker (with an autonomous-provenance body block — see
|
||||
`../boss/SKILL.md` § Skill-system feedback). This skill is the shared
|
||||
convention they lean on.
|
||||
regressions, and `boss` files skill-system deficiencies (with an
|
||||
autonomous-provenance body block — see `../boss/SKILL.md` § Skill-system
|
||||
feedback) and logs each fork decision on the run's reference issue (§ The
|
||||
reference issue). This skill is the shared convention they lean on.
|
||||
|
||||
## The four writing rules
|
||||
|
||||
@@ -96,22 +102,56 @@ These apply to every issue, on create and on edit.
|
||||
- Avoid: "parser bug" / "There is a problem with the parser."
|
||||
- Use: "Preserve backslash escapes in quoted strings"
|
||||
|
||||
4. **Self-contained — the reachability test.** The issue stands on its
|
||||
own, without the conversation that produced it. Apply one test to
|
||||
every reference: *starting from this entry alone — a reader may have
|
||||
arrived by a direct comment-anchor link, no chat and no sibling
|
||||
comments loaded — can they follow it to its target?* If not, it is a
|
||||
dangling pointer: reproduce the content inline, or swap in a
|
||||
resolvable locator.
|
||||
4. **Self-contained — reachable AND comprehensible.** The issue stands on
|
||||
its own, without the conversation that produced it. Two tests apply to
|
||||
every reference, and a pointer can pass one while failing the other.
|
||||
|
||||
**Reachable — use these:** content stated or quoted inline; an
|
||||
issue/PR number (`#42`, or cross-repo `Skills #11`); a commit SHA
|
||||
(`a1b2c3d`, resolves on push); a full URL; a repo-relative path,
|
||||
optionally with a line range (`parser.rs:84-90`); another comment by
|
||||
its full URL (the link ending `#issuecomment-NNNN` — the bare fragment
|
||||
only resolves in-page on that comment's own issue); a same-entry
|
||||
section marker (`§5`); a convention-resolvable in-repo slug (a
|
||||
`docs/specs/` slug, a cycle number).
|
||||
- **(1) Reachability.** *Starting from this entry alone — a reader may
|
||||
have arrived by a direct comment-anchor link, no chat and no sibling
|
||||
comments loaded — can they follow it to its target?* If not, it is a
|
||||
dangling pointer: reproduce the content inline, or swap in a
|
||||
resolvable locator.
|
||||
- **(2) Comprehension.** Does the issue make its point *without* the
|
||||
reader absorbing what the target says? A human reads linearly and
|
||||
holds no context-wide view; unlike an LLM — which usually has the
|
||||
referenced sources already in its context — a human has only what is
|
||||
on the page. So where the issue's substance leans on what a reference
|
||||
*contains*, state that substance inline beside the pointer: the
|
||||
reference then corroborates or lets the reader go deeper, it does not
|
||||
carry the meaning the issue omits. A pointer can pass (1) and fail
|
||||
(2): `#42` resolves, yet a linear reader still does not know what
|
||||
`#42` says. A *pure further-reading* pointer — one the issue's point
|
||||
does not lean on — needs only to resolve.
|
||||
|
||||
**Reachable — necessary, not sufficient.** Resolving satisfies test (1)
|
||||
only; of the forms below, only *content stated or quoted inline* also
|
||||
passes test (2) unaided.
|
||||
|
||||
**No absolute URL carrying a server name or port** — it rots when the
|
||||
host moves and leaks the deployment; every reference below has a
|
||||
host-free form:
|
||||
- content stated or quoted inline;
|
||||
- an issue/PR number (`#42`; a cross-repo ref needs the `owner/repo#N`
|
||||
form with no space — `Brummel/Skills#11`, not `Skills #11`, which
|
||||
binds `#11` to the current repo) or a commit SHA (`a1b2c3d`, resolves
|
||||
on push) — Gitea auto-links these against the current host;
|
||||
- a **relative Markdown link** — Gitea resolves it against the repo
|
||||
root, so it carries no host in the source or the rendered link: the
|
||||
way to make a file section, a line range, or a specific comment
|
||||
clickable. The base is the repo root, so a file link needs the `src/`
|
||||
segment; without it (`commit/<sha>/…`, `branch/…`) it does not
|
||||
resolve:
|
||||
- a file at a pinned commit —
|
||||
`[what it says](src/commit/<sha>/docs/design.md#user-content-<heading-slug>)`,
|
||||
or a line range `…/parser.rs#L84-L90`; prefer `src/commit/<sha>/…`
|
||||
(immutable) over `src/branch/<branch>/…` (drifts);
|
||||
- a specific comment — `[what it says](issues/N#issuecomment-M)`
|
||||
(a plain `issues/…` path, no `src/`; the bare `#issuecomment-M`
|
||||
fragment alone only resolves in-page on that comment's own issue);
|
||||
- a repo-relative path, optionally with a line range (`parser.rs:84-90`),
|
||||
as a plain locator where a clickable link is not worth building;
|
||||
- a same-entry section marker (`§5`); a convention-resolvable in-repo
|
||||
slug (a `docs/specs/` slug, a cycle number).
|
||||
|
||||
**Unreachable — rewrite or inline; these never resolve from the
|
||||
tracker:**
|
||||
@@ -122,12 +162,13 @@ These apply to every issue, on create and on edit.
|
||||
decision's words inline is fine — see the carve-out below.)
|
||||
- **A weak prose pointer** — "above", "below", "earlier", "the prior
|
||||
comment", "logged above", "as discussed" — with no resolvable
|
||||
locator: the target comment's full URL, a `#N`, or a *same-entry*
|
||||
`§` marker. A `§` pointing into another comment or file is itself
|
||||
unreachable — link that comment's URL.
|
||||
locator: a relative link to the target comment
|
||||
(`issues/N#issuecomment-M`), a `#N`, or a *same-entry* `§` marker. A
|
||||
`§` pointing into another comment or file is itself unreachable —
|
||||
link that comment with `issues/N#issuecomment-M`.
|
||||
- **An artifact named by role, not locator** — "the OOS harness
|
||||
issue", "see the ledger", a `Depends on` target — carrying no `#N` /
|
||||
SHA / URL / repo path.
|
||||
SHA / relative link / repo path.
|
||||
- **A path outside this repo** — `/mnt/...`, `~/.claude/...`, a Claude
|
||||
auto-memory slug, another project's `BLOCKED.md`. Only a path in
|
||||
*this* repo is reachable.
|
||||
@@ -156,7 +197,7 @@ These apply to every issue, on create and on edit.
|
||||
|
||||
- Avoid: "Approach B (the mechanism refinement decided + logged
|
||||
above)." — "logged above" points to a sibling comment with no
|
||||
resolvable URL, so a reader who landed on this comment can't reach
|
||||
resolvable locator, so a reader who landed on this comment can't reach
|
||||
the refinement; the violation is the unresolvable pointer, and it
|
||||
stands even when the mechanism is restated inline. The bare label
|
||||
"Approach B" compounds it — it indexes an A/B fork this entry never
|
||||
@@ -165,12 +206,19 @@ These apply to every issue, on create and on edit.
|
||||
- Use — drop the chat-native label, name the option on its own terms,
|
||||
then inline or link the refinement: "The honest per-held-cycle bleed
|
||||
(accrue each held cycle, dump at close) — refined in
|
||||
`http://…/issues/148#issuecomment-2142`."
|
||||
[issue 148's comment](issues/148#issuecomment-2142)."
|
||||
|
||||
**Language:** title and body are English — an issue is a repo
|
||||
artefact mirrored to Gitea ("would it be committed → English", per
|
||||
`~/dev/CLAUDE.md`).
|
||||
|
||||
**Milestones** obey the same conventions, with one adjustment. A milestone
|
||||
is a container — a big chunk, usually carrying a spec — so its title
|
||||
*names* the container ("Cycle 7 — streaming rewrite") rather than taking
|
||||
rule 3's imperative verb form. Its description obeys rules 1 (impersonal
|
||||
and tool-neutral), 2 (validated or flagged) and 4 (reachable and
|
||||
comprehensible) exactly as an issue body does.
|
||||
|
||||
## tea mechanics
|
||||
|
||||
`tea` is pre-authenticated via its own config (`~/.config/tea/`).
|
||||
@@ -188,6 +236,9 @@ CLAUDE.md project facts name the repo slug and the list/show commands).
|
||||
| Re-label | `tea issues edit <idx> --add-labels a --remove-labels b` |
|
||||
| Comment | `tea comment <idx> "<body>"` |
|
||||
| Close / reopen | `tea issues close <idx>` / `tea issues reopen <idx>` |
|
||||
| List milestones | `tea milestones ls --state open` |
|
||||
| Create milestone | `tea milestones create -t "<title>" -d "<description>"` |
|
||||
| Close / reopen milestone | `tea milestones close "<name>"` / `tea milestones reopen "<name>"` |
|
||||
|
||||
Notes:
|
||||
- The body flag is `--description`/`-d`, **not** `--body`. For a
|
||||
@@ -206,6 +257,11 @@ Notes:
|
||||
- Routine closing is done by a `closes #N` line in the commit body on
|
||||
push (per `~/dev/CLAUDE.md`); `tea issues close` is for closing
|
||||
without an accompanying commit.
|
||||
- `tea milestones` has no `edit` subcommand (create / list / close /
|
||||
reopen / delete only). To change a milestone's title or description,
|
||||
use the Gitea API (`PATCH /api/v1/repos/<owner>/<repo>/milestones/<id>`,
|
||||
the numeric `<id>` from `tea milestones ls --fields title,id`); the
|
||||
reachable-and-comprehensible conventions apply to the new description.
|
||||
|
||||
## Common mistakes
|
||||
|
||||
@@ -218,10 +274,12 @@ Notes:
|
||||
| `-d` body with a guessed flag (`--body`) | tea rejects it | `--description`/`-d` |
|
||||
| Editing without viewing first | Clobbers others' edits | `tea issues <idx>`, then edit |
|
||||
| Reading/echoing tea's config | Token leak | tea is already authenticated |
|
||||
| Pointer to the chat that produced the entry ("in-context", "the cycle transcript", a juror code) | The chat is invisible to a tracker reader — never reachable | Quote the words inline, or log the decision to the tracker and cite that comment's full URL |
|
||||
| "above" / "below" / "the prior comment" with no anchor | A reader on a direct comment link can't tell which entry | Add the comment's full URL, a `#N`, or a *same-entry* `§` marker |
|
||||
| Artifact or path named without a locator — "the harness issue", "see the ledger", `/mnt/...`, `~/.claude/...` | Nothing to navigate to from the tracker | Supply a `#N`, SHA, URL, or in-repo path — or reproduce the fact inline |
|
||||
| Pointer to the chat that produced the entry ("in-context", "the cycle transcript", a juror code) | The chat is invisible to a tracker reader — never reachable | Quote the words inline, or log the decision to the tracker and cite that comment with a relative link (`issues/N#issuecomment-M`) |
|
||||
| "above" / "below" / "the prior comment" with no anchor | A reader on a direct comment link can't tell which entry | Add a relative link to the comment (`issues/N#issuecomment-M`), a `#N`, or a *same-entry* `§` marker |
|
||||
| Artifact or path named without a locator — "the harness issue", "see the ledger", `/mnt/...`, `~/.claude/...` | Nothing to navigate to from the tracker | Supply a `#N`, SHA, in-repo path, or relative link — or reproduce the fact inline |
|
||||
| Bare un-glossed code or ordinal (`I7`, `C16`, "decision #5") | Its defining set isn't in the entry | Gloss it inline, or restate the set |
|
||||
| A reachable ref the point leans on, left un-glossed (`Blocked on #42`; "see `parser.rs:84` for the mechanism") | Resolves (test 1) but a linear reader learns nothing (test 2 fails) | Gloss the substance inline; attach the link as the go-deeper pointer |
|
||||
| An absolute URL with a server name or port (`http://host:port/…`) | Rots when the host moves; leaks the deployment | Host-free form — `#N`, a relative `issues/N#issuecomment-M`, or `src/commit/<sha>/path#…` |
|
||||
|
||||
## Red flags — STOP
|
||||
|
||||
@@ -233,18 +291,26 @@ Notes:
|
||||
*work*, or a readiness status, is not what this flags)
|
||||
- A factual statement with neither evidence nor a "claim" flag
|
||||
- A title that is a noun phrase or ends with a period
|
||||
- A reference with no resolvable locator (`#N`, a commit SHA, a URL, an
|
||||
existing repo path, a `docs/specs/` slug or cycle number, a same-entry
|
||||
`§`, or the fact reproduced inline), or a bare never-glossed code whose
|
||||
defining set isn't in the entry — in particular:
|
||||
- A reference with no resolvable locator (`#N`, a commit SHA, a host-free
|
||||
relative link like `issues/N#issuecomment-M` or `src/commit/<sha>/path`,
|
||||
an existing repo path, a `docs/specs/` slug or cycle number, a
|
||||
same-entry `§`, or the fact reproduced inline), or a bare never-glossed
|
||||
code whose defining set isn't in the entry — in particular:
|
||||
- a pointer to the chat that produced the entry ("in-context", "the
|
||||
cycle transcript", a juror code); the chat is never tracker-reachable
|
||||
- "above" / "below" / "the prior comment" / "as discussed" with no
|
||||
resolvable locator — the comment's full URL, a `#N`, or a same-entry `§`
|
||||
resolvable locator — a relative link to the comment
|
||||
(`issues/N#issuecomment-M`), a `#N`, or a same-entry `§`
|
||||
- an out-of-repo path (`/mnt`, `~/.claude`, a `memory <slug>`,
|
||||
another project's `.md`) cited as the basis
|
||||
- a `#`-token that resolves to nothing — a `#(A)` placeholder or a
|
||||
wrong-format `#0071`
|
||||
- An absolute URL carrying a server name or port anywhere in title or body
|
||||
— use the host-free relative form (`issues/N#issuecomment-M`,
|
||||
`src/commit/<sha>/path#…`)
|
||||
- A reachable reference the entry's point leans on, its substance not
|
||||
glossed inline — a linear reader can't grasp the entry without navigating
|
||||
away (the comprehension test, rule 4)
|
||||
- About to `tea issues edit` without having viewed the issue
|
||||
- About to print or `cat` the tea config
|
||||
|
||||
|
||||
Reference in New Issue
Block a user