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:
2026-07-01 13:51:40 +02:00
parent c39a817982
commit 1a1077b7f7
2 changed files with 112 additions and 45 deletions
+8 -7
View File
@@ -304,8 +304,8 @@ things at once:
remains of the dead-ended line. remains of the dead-ended line.
These decision-log comments are issue entries — they obey These decision-log comments are issue entries — they obey
`../issue/SKILL.md`: rule 1 (impersonal and tool-neutral) and rule 4 (the `../issue/SKILL.md`: rule 1 (impersonal and tool-neutral) and rule 4
reachability test). A later run or user lands on the **comment**, not the (reachable and comprehensible). A later run or user lands on the **comment**, not the
chat that produced it, so each must be self-contained, reachable from the chat that produced it, so each must be self-contained, reachable from the
tracker, and free of this loop's own control-flow. tracker, and free of this loop's own control-flow.
@@ -316,9 +316,10 @@ tracker, and free of this loop's own control-flow.
- **Reproduce each fork's options and chosen rationale inline.** A bare - **Reproduce each fork's options and chosen rationale inline.** A bare
label ("Approach B") indexes a set the reader cannot see — spell the label ("Approach B") indexes a set the reader cannot see — spell the
options out, or name the choice on its own terms. options out, or name the choice on its own terms.
- **Tie a later comment to an earlier one by that comment's full URL, or - **Tie a later comment to an earlier one by a host-free relative link to
restate the point** — never "above" / "logged above" / "the prior that comment (`issues/N#issuecomment-M`), or restate the point** —
comment", which a reader on a direct comment-anchor link cannot resolve. never "above" / "logged above" / "the prior comment", which a reader on a
direct comment-anchor link cannot resolve.
- **Record the decision, not the dispatch.** The comment logs what was - **Record the decision, not the dispatch.** The comment logs what was
decided and why, and may carry a durable, tool-neutral readiness status decided and why, and may carry a durable, tool-neutral readiness status
("design settled — ready for spec production"). It never writes this ("design settled — ready for spec production"). It never writes this
@@ -693,7 +694,7 @@ the user wants it — there is no autonomous filing to govern.
| "This spec is clearly good — I'll sign it on my judgement" | Your judgement is not the signature; the Step-5 `grounding-check` `PASS` is. Run grounding and sign on the PASS. A no-override grounding `BLOCK` routes to the human — never signed over on confidence. (The old unanimous `spec-skeptic` panel is retired; do not re-introduce it as a gate.) | | "This spec is clearly good — I'll sign it on my judgement" | Your judgement is not the signature; the Step-5 `grounding-check` `PASS` is. Run grounding and sign on the PASS. A no-override grounding `BLOCK` routes to the human — never signed over on confidence. (The old unanimous `spec-skeptic` panel is retired; do not re-introduce it as a gate.) |
| "There's an open fork — I'll bounce to `brainstorm` to be safe" | If you can *derive* an answer (sources, code, consistency, risk), decide it boldly and record it in the reference issue. Only a *pure-preference* fork bounces. Bouncing a derivable fork is exactly the timidity the bold stance retired; unsure if your leaning is bias, pull one ad-hoc `spec-skeptic` lens, then decide. | | "There's an open fork — I'll bounce to `brainstorm` to be safe" | If you can *derive* an answer (sources, code, consistency, risk), decide it boldly and record it in the reference issue. Only a *pure-preference* fork bounces. Bouncing a derivable fork is exactly the timidity the bold stance retired; unsure if your leaning is bias, pull one ad-hoc `spec-skeptic` lens, then decide. |
| "I derived a fork but didn't bother logging it on the issue" | The reference-issue comment is mandatory. It is the user's only window into a call made without them — and, because a rollback hard-drops the commits, the only surviving trace of the attempt. No reference issue, no fork decision: create the seeding issue first. | | "I derived a fork but didn't bother logging it on the issue" | The reference-issue comment is mandatory. It is the user's only window into a call made without them — and, because a rollback hard-drops the commits, the only surviving trace of the attempt. No reference issue, no fork decision: create the seeding issue first. |
| "The user was in the discussion, so 'as decided in-context / above' is enough on the issue" | The decision log is read later by a run or user who was NOT in that discussion and may land on the comment alone. Quote the user's words + date inline, reproduce the fork's options and rationale, and link any sibling comment by its full URL — never "above" / "in-context". The chat is not reachable from the tracker (`../issue/SKILL.md` rule 4). | | "The user was in the discussion, so 'as decided in-context / above' is enough on the issue" | The decision log is read later by a run or user who was NOT in that discussion and may land on the comment alone. Quote the user's words + date inline, reproduce the fork's options and rationale, and link any sibling comment by a host-free relative link (`issues/N#issuecomment-M`) — never "above" / "in-context". The chat is not reachable from the tracker (`../issue/SKILL.md` rule 4). |
| "I resolved the fork — I'll note that `specify` runs next so the thread is actionable" | The decision log records the decision and a tool-neutral readiness status, never this loop's dispatch. Directing who runs what next is session control-flow whether the skill is named ("dispatch `implement` next") or periphrased ("hand it to the spec writer") — meaningless to a later reader who isn't the loop, and declarative phrasing doesn't save it; "what's next" lives in the issue's open/labelled state (`../issue/SKILL.md` rule 1). | | "I resolved the fork — I'll note that `specify` runs next so the thread is actionable" | The decision log records the decision and a tool-neutral readiness status, never this loop's dispatch. Directing who runs what next is session control-flow whether the skill is named ("dispatch `implement` next") or periphrased ("hand it to the spec writer") — meaningless to a later reader who isn't the loop, and declarative phrasing doesn't save it; "what's next" lives in the issue's open/labelled state (`../issue/SKILL.md` rule 1). |
| "Auto-sign let me continue, so I don't need to notify — it's just progress" | The auto-sign notify is mandatory and carries a decision (the user's veto over a signature made without them). It is the one sanctioned mid-flow notify precisely because it is not progress — it is the audit trail for a delegated gate. | | "Auto-sign let me continue, so I don't need to notify — it's just progress" | The auto-sign notify is mandatory and carries a decision (the user's veto over a signature made without them). It is the one sanctioned mid-flow notify precisely because it is not progress — it is the audit trail for a delegated gate. |
| "I hit a gap in the skill system itself — I should notify the user about it" | No. File it on the plugin's own tracker with an autonomous-provenance body block and continue (§ Skill-system feedback). It needs no mid-run decision, so notifying would be the attention-burning progress ping the notify discipline forbids; the filed issue is the durable record. | | "I hit a gap in the skill system itself — I should notify the user about it" | No. File it on the plugin's own tracker with an autonomous-provenance body block and continue (§ Skill-system feedback). It needs no mid-run decision, so notifying would be the attention-burning progress ping the notify discipline forbids; the filed issue is the durable record. |
@@ -716,7 +717,7 @@ the user wants it — there is no autonomous filing to govern.
- About to re-introduce the retired `spec-skeptic` panel as a sign gate (a unanimous five-juror pass as a precondition) — it is now only the optional Step-1.5 bias-breaker; or to run any auto-sign path outside a `/boss` session, or to skip the mandatory auto-sign notify after signing. - About to re-introduce the retired `spec-skeptic` panel as a sign gate (a unanimous five-juror pass as a precondition) — it is now only the optional Step-1.5 bias-breaker; or to run any auto-sign path outside a `/boss` session, or to skip the mandatory auto-sign notify after signing.
- About to *decide* a fork that hangs on pure user preference (no derivable better) instead of bouncing it — or its inverse, bouncing a *derivable* fork to `brainstorm` out of timidity. - About to *decide* a fork that hangs on pure user preference (no derivable better) instead of bouncing it — or its inverse, bouncing a *derivable* fork to `brainstorm` out of timidity.
- About to make a fork decision without recording it on the run's reference issue, or to run autonomously with no reference issue at all. - About to make a fork decision without recording it on the run's reference issue, or to run autonomously with no reference issue at all.
- About to record a fork decision that points at the chat ("settled in the discussion", "decided in-context") or at an earlier comment by "above" / "logged above" — the decision log is tracker-reachable per `../issue/SKILL.md` rule 4: quote the provenance and reproduce the options inline, and link a sibling comment by its full URL. - About to record a fork decision that points at the chat ("settled in the discussion", "decided in-context") or at an earlier comment by "above" / "logged above" — the decision log is tracker-reachable per `../issue/SKILL.md` rule 4: quote the provenance and reproduce the options inline, and link a sibling comment by a host-free relative link (`issues/N#issuecomment-M`).
- About to write this loop's next dispatch into a decision-log comment — whether a skill is named ("enter `specify` from here", "next: dispatch `implement`") or periphrased ("hand it to the spec writer next") — instead of a tool-neutral readiness status; which actor runs next is this loop's Step 3/4, not an issue fact (`../issue/SKILL.md` rule 1). - About to write this loop's next dispatch into a decision-log comment — whether a skill is named ("enter `specify` from here", "next: dispatch `implement`") or periphrased ("hand it to the spec writer next") — instead of a tool-neutral readiness status; which actor runs next is this loop's Step 3/4, not an issue fact (`../issue/SKILL.md` rule 1).
- About to `git reset` below the session anchor, or to `reset` a commit that has been pushed — the rollback sandbox is the orchestrator's *own unpushed* commits above the anchor only; user-ratified and pushed history is forward-only (`git revert`). - About to `git reset` below the session anchor, or to `reset` a commit that has been pushed — the rollback sandbox is the orchestrator's *own unpushed* commits above the anchor only; user-ratified and pushed history is forward-only (`git revert`).
- About to notify the user about a skill-system deficiency instead of filing it on the plugin's own tracker and continuing (§ Skill-system feedback) — it is captured, never a notify event. - About to notify the user about a skill-system deficiency instead of filing it on the plugin's own tracker and continuing (§ Skill-system feedback) — it is captured, never a notify event.
+104 -38
View File
@@ -1,6 +1,6 @@
--- ---
name: issue 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 # 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 An issue is a durable artefact in the forward-queue, read later by
humans and by other agents — usually without the conversation that humans and by other agents — usually without the conversation that
produced it. It must stand on its own. This skill unifies how issue produced it, and a human reads it linearly, holding only what is on the
text is written so every issue reads the same way, and records the page. It must stand on its own. This skill unifies how issue text is
`tea` mechanics for creating and editing them. 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 An issue states facts and clearly-flagged claims about a concern. It
is not a chat message. 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 | | "Open an issue for X" / "file a bug about Y" | Yes |
| "Edit / re-label / comment on issue #N" | Yes | | "Edit / re-label / comment on issue #N" | Yes |
| "Close #N" (outside a `closes #N` commit) | 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 | | Turning a finding or deferred work into a tracker item | Yes |
| A note relevant only to the current conversation | No | | 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 `brainstorm` parks a deferred spec as a backlog issue, `audit` files
regressions, and `boss` files skill-system deficiencies against the regressions, and `boss` files skill-system deficiencies (with an
plugin's own tracker (with an autonomous-provenance body block — see autonomous-provenance body block — see `../boss/SKILL.md` § Skill-system
`../boss/SKILL.md` § Skill-system feedback). This skill is the shared feedback) and logs each fork decision on the run's reference issue (§ The
convention they lean on. reference issue). This skill is the shared convention they lean on.
## The four writing rules ## 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." - Avoid: "parser bug" / "There is a problem with the parser."
- Use: "Preserve backslash escapes in quoted strings" - Use: "Preserve backslash escapes in quoted strings"
4. **Self-contained — the reachability test.** The issue stands on its 4. **Self-contained — reachable AND comprehensible.** The issue stands on
own, without the conversation that produced it. Apply one test to its own, without the conversation that produced it. Two tests apply to
every reference: *starting from this entry alone — a reader may have every reference, and a pointer can pass one while failing the other.
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.
**Reachable — use these:** content stated or quoted inline; an - **(1) Reachability.** *Starting from this entry alone — a reader may
issue/PR number (`#42`, or cross-repo `Skills #11`); a commit SHA have arrived by a direct comment-anchor link, no chat and no sibling
(`a1b2c3d`, resolves on push); a full URL; a repo-relative path, comments loaded — can they follow it to its target?* If not, it is a
optionally with a line range (`parser.rs:84-90`); another comment by dangling pointer: reproduce the content inline, or swap in a
its full URL (the link ending `#issuecomment-NNNN` — the bare fragment resolvable locator.
only resolves in-page on that comment's own issue); a same-entry - **(2) Comprehension.** Does the issue make its point *without* the
section marker (`§5`); a convention-resolvable in-repo slug (a reader absorbing what the target says? A human reads linearly and
`docs/specs/` slug, a cycle number). 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 **Unreachable — rewrite or inline; these never resolve from the
tracker:** 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.) decision's words inline is fine — see the carve-out below.)
- **A weak prose pointer** — "above", "below", "earlier", "the prior - **A weak prose pointer** — "above", "below", "earlier", "the prior
comment", "logged above", "as discussed" — with no resolvable comment", "logged above", "as discussed" — with no resolvable
locator: the target comment's full URL, a `#N`, or a *same-entry* locator: a relative link to the target comment
`§` marker. A `§` pointing into another comment or file is itself (`issues/N#issuecomment-M`), a `#N`, or a *same-entry* `§` marker. A
unreachable — link that comment's URL. `§` 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 - **An artifact named by role, not locator** — "the OOS harness
issue", "see the ledger", a `Depends on` target — carrying no `#N` / 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 - **A path outside this repo** — `/mnt/...`, `~/.claude/...`, a Claude
auto-memory slug, another project's `BLOCKED.md`. Only a path in auto-memory slug, another project's `BLOCKED.md`. Only a path in
*this* repo is reachable. *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 - Avoid: "Approach B (the mechanism refinement decided + logged
above)." — "logged above" points to a sibling comment with no 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 the refinement; the violation is the unresolvable pointer, and it
stands even when the mechanism is restated inline. The bare label stands even when the mechanism is restated inline. The bare label
"Approach B" compounds it — it indexes an A/B fork this entry never "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, - 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 then inline or link the refinement: "The honest per-held-cycle bleed
(accrue each held cycle, dump at close) — refined in (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 **Language:** title and body are English — an issue is a repo
artefact mirrored to Gitea ("would it be committed → English", per artefact mirrored to Gitea ("would it be committed → English", per
`~/dev/CLAUDE.md`). `~/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 mechanics
`tea` is pre-authenticated via its own config (`~/.config/tea/`). `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` | | Re-label | `tea issues edit <idx> --add-labels a --remove-labels b` |
| Comment | `tea comment <idx> "<body>"` | | Comment | `tea comment <idx> "<body>"` |
| Close / reopen | `tea issues close <idx>` / `tea issues reopen <idx>` | | 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: Notes:
- The body flag is `--description`/`-d`, **not** `--body`. For a - 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 - 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 push (per `~/dev/CLAUDE.md`); `tea issues close` is for closing
without an accompanying commit. 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 ## Common mistakes
@@ -218,10 +274,12 @@ Notes:
| `-d` body with a guessed flag (`--body`) | tea rejects it | `--description`/`-d` | | `-d` body with a guessed flag (`--body`) | tea rejects it | `--description`/`-d` |
| Editing without viewing first | Clobbers others' edits | `tea issues <idx>`, then edit | | Editing without viewing first | Clobbers others' edits | `tea issues <idx>`, then edit |
| Reading/echoing tea's config | Token leak | tea is already authenticated | | 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 | | 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 the comment's full URL, a `#N`, or a *same-entry* `§` marker | | "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, URL, or in-repo path — or reproduce the fact inline | | 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 | | 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 ## Red flags — STOP
@@ -233,18 +291,26 @@ Notes:
*work*, or a readiness status, is not what this flags) *work*, or a readiness status, is not what this flags)
- A factual statement with neither evidence nor a "claim" flag - A factual statement with neither evidence nor a "claim" flag
- A title that is a noun phrase or ends with a period - 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 - A reference with no resolvable locator (`#N`, a commit SHA, a host-free
existing repo path, a `docs/specs/` slug or cycle number, a same-entry relative link like `issues/N#issuecomment-M` or `src/commit/<sha>/path`,
`§`, or the fact reproduced inline), or a bare never-glossed code whose an existing repo path, a `docs/specs/` slug or cycle number, a
defining set isn't in the entry — in particular: 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 - a pointer to the chat that produced the entry ("in-context", "the
cycle transcript", a juror code); the chat is never tracker-reachable cycle transcript", a juror code); the chat is never tracker-reachable
- "above" / "below" / "the prior comment" / "as discussed" with no - "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>`, - an out-of-repo path (`/mnt`, `~/.claude`, a `memory <slug>`,
another project's `.md`) cited as the basis another project's `.md`) cited as the basis
- a `#`-token that resolves to nothing — a `#(A)` placeholder or a - a `#`-token that resolves to nothing — a `#(A)` placeholder or a
wrong-format `#0071` 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 `tea issues edit` without having viewed the issue
- About to print or `cat` the tea config - About to print or `cat` the tea config