docs(kyberforge): body-discipline.md and the ADR's cited dispatch exemplar cannot both be satisfied #109

Closed
opened 2026-08-30 12:40:36 +00:00 by Claude · 1 comment
Collaborator

references/body-discipline.md requires every reference file to be wired with the literal conditional form If <condition>, read `references/<file>.md` and calls a generic pointer a Vale error.

plugins/kyberforge/.apm/skills/apm-workflow/SKILL.md:33-41 — which ADR-0020 names by name as the dispatch-pattern exemplar, and which skill-author/references/contract.md:123 cites for its 421-word body dispatching to ~3,000 words of references — uses a bare dispatch table plus one generic line: "Read only the reference file matching the requested action."

An author cannot satisfy both. Following the rule means stating every condition twice — once as a table row, once as a literal conditional — in a body whose whole purpose is to be short.

How it surfaced

gitea-workflow's retrofit (#99) hit this directly. Its 227-word body ended up carrying both forms:

  • SKILL.md:31-35 — a dispatch table mapping three invocation shapes to three reference files
  • SKILL.md:37-41 — the same three mappings again as literal conditionals

It chose the redundant superset because the gate is hot and a Vale error blocks. That is the rational choice under the current rules, and it will recur in every retrofit — the contradiction reliably produces duplication in exactly the files the contract is trying to keep lean.

Options

  1. Exempt a body that already carries a dispatch table. The table is the conditional wiring; a row is a condition and a target. This is what apm-workflow does and what the ADR points at.
  2. Drop the table, keep only the literal conditionals. Consistent, but loses the at-a-glance routing view for skills with many branches.
  3. Keep both and say so explicitly, accepting the duplication as the price of the Vale rule.

Recommend 1: make the literal-conditional requirement apply only where there is no dispatch table, and say so in body-discipline.md. That aligns the rule with the exemplar the ADR already endorses, and removes a duplication the ADR would otherwise flag as capability restatement.

Files

  • plugins/kyberforge/.apm/skills/skill-audit/references/body-discipline.md — the rule
  • plugins/kyberforge/.apm/skills/apm-workflow/SKILL.md:33-41 — the exemplar that contradicts it
  • The Vale rule enforcing the generic-pointer error, under plugins/kyberforge/.apm/skills/*/assets/vale/styles/Kyberforge/

Note apm-workflow is itself still a #99 retrofit target (description 817 chars). Resolving this first would avoid that retrofit having to guess which convention to follow — and whichever way it goes, the exemplar and the rule should agree afterwards.

Found during the gitea wave of #99. See also #107 (resolver under-reports boundary coverage).

`references/body-discipline.md` requires every reference file to be wired with the literal conditional form ``If <condition>, read `references/<file>.md` `` and calls a generic pointer a Vale error. `plugins/kyberforge/.apm/skills/apm-workflow/SKILL.md:33-41` — which ADR-0020 names by name as **the** dispatch-pattern exemplar, and which `skill-author/references/contract.md:123` cites for its 421-word body dispatching to ~3,000 words of references — uses a bare dispatch table plus one generic line: *"Read only the reference file matching the requested action."* An author cannot satisfy both. Following the rule means stating every condition twice — once as a table row, once as a literal conditional — in a body whose whole purpose is to be short. ## How it surfaced `gitea-workflow`'s retrofit (#99) hit this directly. Its 227-word body ended up carrying both forms: - `SKILL.md:31-35` — a dispatch table mapping three invocation shapes to three reference files - `SKILL.md:37-41` — the same three mappings again as literal conditionals It chose the redundant superset because the gate is hot and a Vale error blocks. That is the rational choice under the current rules, and it will recur in every retrofit — the contradiction reliably produces duplication in exactly the files the contract is trying to keep lean. ## Options 1. **Exempt a body that already carries a dispatch table.** The table *is* the conditional wiring; a row is a condition and a target. This is what `apm-workflow` does and what the ADR points at. 2. **Drop the table, keep only the literal conditionals.** Consistent, but loses the at-a-glance routing view for skills with many branches. 3. **Keep both and say so explicitly**, accepting the duplication as the price of the Vale rule. Recommend 1: make the literal-conditional requirement apply only where there is no dispatch table, and say so in `body-discipline.md`. That aligns the rule with the exemplar the ADR already endorses, and removes a duplication the ADR would otherwise flag as capability restatement. ## Files - `plugins/kyberforge/.apm/skills/skill-audit/references/body-discipline.md` — the rule - `plugins/kyberforge/.apm/skills/apm-workflow/SKILL.md:33-41` — the exemplar that contradicts it - The Vale rule enforcing the generic-pointer error, under `plugins/kyberforge/.apm/skills/*/assets/vale/styles/Kyberforge/` Note `apm-workflow` is itself still a #99 retrofit target (description 817 chars). Resolving this first would avoid that retrofit having to guess which convention to follow — and whichever way it goes, the exemplar and the rule should agree afterwards. ## Related Found during the `gitea` wave of #99. See also #107 (resolver under-reports boundary coverage).
Claude added this to the Skills & Agents milestone 2026-08-30 12:40:36 +00:00
Claude added the Kind/Documentation
Priority
Medium
3
labels 2026-08-30 12:40:36 +00:00
Author
Collaborator

Resolved with option 1. Two corrections to the issue as filed, both worth recording because they change the size of the fix.

There is no Vale conflict

The issue says the rule "calls a generic pointer a Vale error" and lists a Vale rule under Kyberforge/ as one of the three files to change. Checked: the rule is PaddingPhrase.yml, and it is far narrower than the prose suggests.

raw:
  - 'see references?/? for (more )?(info|information|details)\b'

That matches "see references/ for more info" and nothing else. It does not match apm-workflow's closing line, "Read only the reference file matching the requested action." The linter and the exemplar never disagreed.

The contradiction was entirely in the prose rule at body-discipline.md:31-34 — "the literal conditional form, never a generic pointer" — which an LLM auditor reads and applies literally, exactly as gitea-workflow's retrofit did. So the fix is one file, not three, and no Vale rule changes.

What changed

plugins/kyberforge/.apm/skills/skill-audit/references/body-discipline.md:

  • The move-to-references/ rule now carries an explicit exemption: a dispatch table satisfies the wiring requirement on its own. A row already pairs a condition with a target, which is what the literal form encodes. Where a body dispatches, audit the table for condition/target completeness and stop. The literal form is what a body needs when it loads a reference without a table — a mid-procedure deepening, an escape hatch, an error path.
  • The dispatch section now quotes apm-workflow's actual wiring (three-column table closed by one line) and says in terms: that is the endorsed shape, do not flag it.

Collateral fixed

gitea-workflow carried the redundant superset this issue predicted — a three-row dispatch table at SKILL.md:29-33 and the same three mappings restated as literal conditionals at :35-39. The three restatements are gone, replaced by the one-line apm-workflow form. Body drops from 227 to 148 words. skill-size-check exits 0, Vale prefilter passes.

On the sequencing note

The issue observes that apm-workflow is itself a #99 retrofit target and that resolving this first spares its retrofit a guess. That still holds — it is wave 4, and this is now settled before it starts, which is why this was done mid-wave-3 rather than after. The change is strictly relaxing: anything written against the old, stricter rule still passes the new one, so no in-flight work was invalidated.

Resolved with option 1. Two corrections to the issue as filed, both worth recording because they change the size of the fix. ## There is no Vale conflict The issue says the rule "calls a generic pointer a Vale error" and lists a Vale rule under `Kyberforge/` as one of the three files to change. Checked: the rule is `PaddingPhrase.yml`, and it is far narrower than the prose suggests. ```yaml raw: - 'see references?/? for (more )?(info|information|details)\b' ``` That matches "see references/ for more info" and nothing else. It does **not** match `apm-workflow`'s closing line, "Read only the reference file matching the requested action." The linter and the exemplar never disagreed. The contradiction was entirely in the **prose rule** at `body-discipline.md:31-34` — "the literal conditional form, never a generic pointer" — which an LLM auditor reads and applies literally, exactly as `gitea-workflow`'s retrofit did. So the fix is one file, not three, and no Vale rule changes. ## What changed `plugins/kyberforge/.apm/skills/skill-audit/references/body-discipline.md`: - The move-to-`references/` rule now carries an explicit exemption: **a dispatch table satisfies the wiring requirement on its own.** A row already pairs a condition with a target, which is what the literal form encodes. Where a body dispatches, audit the table for condition/target completeness and stop. The literal form is what a body needs when it loads a reference *without* a table — a mid-procedure deepening, an escape hatch, an error path. - The dispatch section now quotes `apm-workflow`'s actual wiring (three-column table closed by one line) and says in terms: that is the endorsed shape, do not flag it. ## Collateral fixed `gitea-workflow` carried the redundant superset this issue predicted — a three-row dispatch table at `SKILL.md:29-33` and the same three mappings restated as literal conditionals at `:35-39`. The three restatements are gone, replaced by the one-line `apm-workflow` form. Body drops from 227 to 148 words. `skill-size-check` exits 0, Vale prefilter passes. ## On the sequencing note The issue observes that `apm-workflow` is itself a #99 retrofit target and that resolving this first spares its retrofit a guess. That still holds — it is wave 4, and this is now settled before it starts, which is why this was done mid-wave-3 rather than after. The change is strictly *relaxing*: anything written against the old, stricter rule still passes the new one, so no in-flight work was invalidated.
Sign in to join this conversation.