Commit Graph

8 Commits

Author SHA1 Message Date
a6434e0cdb docs: amend ADR-0021 and close the loose ends ADR-0024 left behind
A six-agent review of today's commits found three documentation defects
that the apm-only change left behind. All three are records that describe
deleted machinery in the present tense; no code or gate is affected.

ADR-0021 was the one ADR that ADR-0024 invalidates without carrying an
amendment note -- 0001, 0006, 0011, 0013, 0014, 0015, 0017, 0018 and 0019
all got one. Its Context section still compiles a plugin description into
four generated files and its Consequences section still names eight, but
718c79a deleted the per-plugin manifest pairs and 0dffff3 deleted the
.github/plugin/marketplace.json mirror. One target survives. The decision
itself is untouched: the note marks the counts historical rather than
rewriting them, since the staleness hazard that motivated the ADR is
exactly what shrinking the blast radius does not fix.

That note also lands the one ADR-0021 has promised since it was written:
its Context section said "see the note below" about the codex profile's
removal and no such note has ever existed in the file.

SIMPLIFICATION-AUDIT.md's section 8 still asked whether Copilot reads the
legacy mirror path. Finding 2c answered that at 11:35 and 0dffff3 acted on
it; two later passes over section 8 (d2480b8, 061bb3d) each checked off a
different question and stepped over this one. Closed with the answer that
already shipped: Copilot's discovery falls through to .claude-plugin/,
so what the deletion cost is discovery-order preference, not consumability.

ADR-0020 cited plugins/bin/skills/zoom-out/SKILL.md:4 as end-to-end
verification evidence. That path is mirror, deleted by ADR-0024. The .apm/
source and the deployed copy both still carry the flag and the pass-through
still holds, so the citation is narrowed to the two live paths rather than
the finding being withdrawn.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YR2CjVumUbEGWcMikcoXBD
2026-09-14 18:38:49 +00:00
Claude Code AI - Gitea MCP
598a7c326a refactor(skills): retrofit the corpus to the ADR-0020 context contract (#129)
Retrofits all 39 skills to ADR-0020's description/body context contract, then fixes what six rounds of independent review found in that retrofit — including four ways the hot gate itself failed open.

Closes #99, #107, #108, #110, #111, #114, #115, #120.

## The retrofit (waves 1-5)

| | Start | Now |
|---|---|---|
| Description FAILs (>400 chars) | 26 | **0** |
| Body FAILs (>900 words, body-only) | 9 | **0** |
| Dangling routing targets | 2 | **0** |
| `Kyberforge.CompositionNote` | 10 | **0** |
| Preload tax | 21,005 chars | **~10,500** |

Under the 12,000-char success criterion. Per-wave detail is on #99.

## The review fixes

**The gate failed open four ways, three of them found after the retrofit shipped.** An unrecognised follower token made a dangling target vanish. A skill directory with no `SKILL.md` resolved as a valid target, so a commit could be green locally and red in a fresh clone — three existing fixtures were relying on that, one of which made the install-leak A/B pass vacuously. Then the free-standing `/name` sweep turned out to be gated on the sentence carrying a boundary marker, so route notation in any other sentence was invisible — not an ERROR, not a SUGGESTION, not an INFO — which left the documented "`/name` always blocks" promise false from a second direction. All four fixed and pinned.

**Two checks were silently not running.** `validate-provenance.sh` checks 7-8 were dead across nine skills. Waking them exposed a deeper problem: they assume `Research doc:` names a source index, but 30 of 121 entries point at topic content documents, so every new check-7 INFO was a false positive and check 8 was saved from a false-FAIL flood only by an *unannounced* skip. Checks 7/8 are now scoped to source indexes and every skip announces itself (#121).

**The retrofit's own anti-goal, four times.** ADR-0020 warns that a blunt gate gets satisfied by deleting content rather than relocating it. `diagnose` and `skill-audit` relocated prose and then read it unconditionally; `prototype` and `vale-config` deleted rules outright that survived nowhere. All four addressed.

## Verification

- `bash tests/run-tests.sh --strict` — 24 suites, 0 skipped, 0 failed
- `bash tests/run-bats.sh` — 325 tests, 0 failures
- `pre-commit run --all-files` — 17/17
- `pre-commit run --hook-stage pre-push --all-files` — 16/16, with `apm marketplace check` and `apm pack --check-clean` run against the remote, not skipped
- `scripts/skill-size-check.sh` over all 39 skills — rc 0, 0 ERROR/FAIL, SUGGESTION-only
- Preload tax measured at **10,498 chars**, max description 390 — both inside budget
- Every new test proven non-vacuous by a deliberate mutation of the behaviour it covers

**Per-commit sync, stated accurately:** the ten commits from the latest review round each pass `check-plugin-content-sync` in isolation, verified by checking each out in a detached worktree with a clean between. The earlier gitea window (`dfacf05..bedbd1d`, nine commits) does **not** — its mirror was regenerated in one batch at `bbc7300`. An earlier revision of this description claimed the property held for every commit; it does not, and a bisect through that window lands on a red commit. **Squash-merge** to collapse it, or accept that this range is not bisectable.

## Version bump

Six plugins and the catalog take a **patch**, not a minor. The branch is **89 commits — 40 `fix` / 30 `refactor` / 12 `docs` / 5 `chore` / 2 `test` — zero `feat`, zero `!`, zero `BREAKING CHANGE`** — and adds no skill, agent, command or hook. (Two earlier revisions of this section cited a stale histogram, most recently 78 commits; the figures above are measured at HEAD.) Both rules this repo ships (`forge/references/version-bump.md`, landing in this PR, and `git-commits/references/conventional-commits-spec.md`) make that a patch, and the catalog set is unchanged at 7 entries.

Not settled by that: four published files were removed from the installed tree, three moved, and `caveman` gained `disable-model-invocation`, retiring its old triggers. Under a strict reading those are major-class and currently ship under `refactor:` with no marker. Whether the deployed skill surface is a public contract is written down nowhere — worth deciding, but it outlives this PR.

## Deliberately not in scope

#112 (cherry-pick ownership, now resolved in favour of `git-commits`), #113 (`rtk git` normalisation), #116 (research fan-out), #101 (audit-skill merge), #122 (non-spec skill-root files), #123 (no PRD producer) stay open. #117 is the one worth reading: the contract's remedy is to move prose into `references/`, which is exactly where neither the size gate nor Vale looks — and the blind spot is wider than #117 currently records, since there is no root `.vale.ini` at all, so every ADR, `CONTEXT.md` and `README.md` is unlinted too.

That blind spot let this branch carry two `level: error` `Kyberforge.SentenceOpenerThereIs` violations into `references/` files it created — `provider-adapter-author/references/provider-matrix.md:31` and `agent-audit/references/finding-criteria.md:95`. Both are reworded in `afadaae`, confirmed by routing each file through the audit's own `vale-wrap.sh` (1 error each before, 0 after). Five further occurrences sit in `references/` files already on `main`; those are the pre-existing corpus and stay with #117, which is the real fix.

Also unfixed and not this PR's: `apm install` appends a duplicate `SessionStart` entry to `.claude/settings.json`, so a fresh clone cannot get pre-push green without an edit AGENTS.md warns against. Reproduces identically on `main`.

Co-authored-by: Defame1297 <gitea@rkdr.net>
Reviewed-on: https://git.dev.rkdr.net/Defame1297/holocron/pulls/129
Co-authored-by: Claude Code AI - Gitea MCP <claude@noreply.git.dev.rkdr.net>
Co-committed-by: Claude Code AI - Gitea MCP <claude@noreply.git.dev.rkdr.net>
2026-09-01 13:47:46 +00:00
54d7bd80ba docs: rule host built-ins out of the routing target universe
Closes the second open design decision on PR #103. The `/compact` finding was
recorded as a false positive needing an allowlist or a suppression mechanism.
It is neither: the routing universe is the apm marketplace, so a target either
resolves to a skill or an agent or it does not resolve, and `/compact`,
`/clear` and `/init` are Claude Code slash commands with no counterpart in
Copilot CLI or Codex. `.apm/` source compiles for all three, so a
vendor-neutral description routing to one is a portability defect and the hard
FAIL is a true positive.

An allowlist was rejected for a concrete reason, not a stylistic one: it
answers a different question ("does this exist on some host?"), it cannot
answer that portably from a single source file, and it goes stale the next
time a host ships a command — reintroducing the same-commit-two-verdicts
failure ADR-0020 already closed for deployed trees.

Nothing is blocked today: zero of the 43 descriptions name a host built-in,
and an author who needs to mention one writes it un-slashed, which is not
route notation and carries no routing claim.

Recorded in ADR-0020 and in both author-facing contract references, so the
next agent reads the decision rather than "fixing" the gate.

ADR: 0020

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-16 20:45:19 +00:00
75a13c82f6 fix(kyberforge): scope corroboration to a real sentence boundary
A prose-form routing target blocks a commit only when its own sentence names
another target that resolves. That makes the sentence splitter part of the
ADR-0020 contract rather than an implementation detail, and the naive
"period, space, capital" rule got it wrong in both directions:

- OVER-SPLIT: `e.g. "..."` is not a sentence end, but the quote looks like a
  start. The clause was cut in half and the corroborator stranded on the far
  side, so a genuinely dangling target silently demoted to SUGGESTION — a
  measurement taken and then discarded, the vacuous-green shape this gate
  exists to prevent. Seven such splits are live in the current corpus.
- UNDER-SPLIT: a sentence opening with a code span or a lowercase skill name
  was not seen as a start, so two sentences merged and a resolving target
  vouched for an unresolvable one it never stood beside — a hard FAIL with no
  escape hatch, which is the exact failure corroboration was added to prevent.

The splitter now excludes the five abbreviations that occur in routing prose
and admits a backtick or lowercase letter as a sentence opener. Applied
byte-identically to all three copies of the shared resolver.

Verified zero-delta against the corpus: 37 ERROR / 58 SUGGESTION / 2 dangling
before and after, findings byte-identical. The exposure this closes is to the
descriptions #99 is about to rewrite, not to the ones already measured — which
is why the deferral reason recorded on PR #103 ("can move the documented corpus
counts") does not hold and the fix lands here rather than after the retrofit.

Three regression tests, one per direction plus the backtick opener, each proven
non-vacuous by reverting the splitter alone and watching it go red.

Refs: #99
ADR: 0020

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-16 20:44:58 +00:00
79c9089122 docs: make the resolution contract match what the gate actually does
Both AGENTS.md and ADR-0020 said deployed .claude/.agents trees are consulted "only
when no authoring root exists". That stopped being true in f7cc279: the walk-up
finds a root in any git repo, so the condition is now whether that root holds
plugins, not whether one was found at all. Left alone, the two documents describe a
resolver that no longer exists — and this repo's prose is load-bearing, since the
next agent reads it instead of the code.

Both now also record why a name-count delta is not an equivalent test, because it is
the obvious simplification and it is wrong: a single-plugin monorepo re-collects its
own package, adds no new name, and would pull the deployed trees back in.

ADR: 0020

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015W3iwF9ncfRZddGBxsMCYi
2026-08-16 19:49:50 +00:00
64ffb9f35a docs: make ADR-0020 match what actually shipped, and record what did not
The ADR was written against base commit `f9b919d` and then not updated as the
implementation moved, so several of its numbers were measuring one thing and being
read as another — the exact conflation the ADR exists to stop, reproduced inside
it. Corrections, all reproducible now that each figure states its method:

- The preload tax is 23,427 chars / ~5,900 tokens, not 23,612 / ~6,200.
- `MAX_WORDS=2770` is a density proxy for the agentskills.io ~5,000-token ceiling,
  not "2× p90". Neither percentile reaches it: 2× the body-only p90 is 2,698 and
  2× the whole-file p90 is 3,052. Reading it as a percentile pairs a whole-file
  gate against a body-only distribution.
- `apm-workflow` is a 421-word body; 554 is its whole-file count. `skill-author`
  and `agent-author` were 2,623 and 2,582 body words — 2,760 and 2,758 whole-file,
  which is where "within twelve words of the gate" comes from. Two numbers for one
  file is the point, and only one of them is what either gate measures.
- Every `file:line` citation now says it resolves against `f9b919d`, since this
  change rewrites most of the cited files.

Three things the ADR asserted that no validator implemented are now filed by tier
in an exhaustive enforcement table — deterministic, prose-pattern, or auditor
judgment — because a rule filed under "Enforcement" that nothing enforces is the
failure mode this ADR is most exposed to. The Gotchas entry count moves to
SUGGESTION to match the script; the paraphrase FAIL is marked as an auditor's,
since semantic equivalence is not pattern-matchable.

Two gaps recorded rather than quietly left:

- The agent body-gate exemption lives in `agent-audit`'s validator and in the
  `skill-size-check` hook's `SKILL.md`-only `files:` pattern — *not* in
  `scripts/skill-size-check.sh`, which measures whatever path it is handed and
  today reports 900-word body FAILs on `git-orchestrate` (933),
  `gitea-orchestrate` (1,199) and `apm-orchestrate` (1,080). Agents escape by file
  pattern, not because the script knows the difference, so widening that pattern
  would silently enforce a gate this ADR declines to set.
- The `skill-audit`/`agent-audit` merge is deferred to #101. This change made the
  split deeper, not shallower: the dispatch retrofit took them from 3 and 4
  reference files to 7 and 8, and their two same-named `description-quality.md`
  files now differ on 100 of ~120 lines after normalising skill/agent. The merge
  reopens ADR-0008 and touches every call site in `skill-author`, `agent-author`
  and `forge`, so it is its own change. #100 carries the dangling-target fixes.

AGENTS.md and CONTEXT.md take the same corrections plus the two live setup
changes: PyYAML is now a hard requirement rather than an optional accelerator (a
fallback that mis-parses an unfamiliar scalar shape reports a clean pass on a file
it never measured), and `.claude/settings.json`'s `pretty-format-json` exclusion is
documented as load-bearing rather than as a tidy-up candidate.

LESSONS.md's autofix entry is corrected on its own provenance, which it got wrong
in both directions. `git log --date=iso` puts the introducing commit at 18:47 and
the fix at 21:54 — three hours, not "weeks" — and `git branch -a --contains` puts
the introducing commit on this branch only, not on main. It was manufactured
inside the same PR that diagnosed it. The added lesson is that "pre-existing" is a
claim about history and history is queryable: a defect found while working on a
branch feels inherited, and the feeling is not evidence.

Refs: ADR-0020, #99, #100, #101
2026-08-16 16:41:45 +00:00
4a5c3c0cff feat(kyberforge): enforce the ADR-0020 context contract for skills and agents
Skill name+description pairs are preloaded into every session, costing
~6,200 tokens across 39 skills before any skill is invoked. The authoring
rules mandated that growth: skill-author:104 and description-quality.md:21
both required padding, while skill-author:102 (the deflating rule) had no
FAIL condition behind it.

Gates (blocking, no baseline file):
- description 250 chars SUGGESTION / 400 FAIL, measured on the folded
  YAML value
- body-only 600 words SUGGESTION / 900 FAIL, independent of the unchanged
  whole-file 2770-word / 500-line spec backstop
- every boundary-clause routing target must resolve to a real skill or
  agent; catches skill-improve, neuledge-context and gitea-labels
- agents take the description gates but deliberately no body gate; a test
  pins that absence

Vale: DescriptionOpener widened to ^This\b, new CompositionNote rule
banning architecture notes from descriptions. 10 hits, 0 false positives.

Kyberforge's own four skills retrofitted: descriptions 3,364 -> 938 chars
(-72%), bodies 8,306 -> 2,487 words (-70%), all via the apm-workflow
dispatch pattern. Fixes the skill-improve dangling route and the
agent-author misroute to manual review.

Also fixes a pre-existing false positive where any line-initial 'read '
was flagged as interactive input, which had already caused two scripts to
be rewritten around it.

Refs: ADR-0020
2026-08-14 21:13:13 +00:00
1c6eababb0 docs(adr): set a context contract for skill and agent authoring
Every installed skill's name+description is preloaded every session -
23,612 chars (~6,200 tokens) across 39 skills. The authoring rules
optimised for triggering reliability with no counter-pressure on size:
skill-author:104 and description-quality.md:21 both mandate padding,
while skill-author:102 (the rule that would deflate it) is
judgment-only and absent from description-quality.md's FAIL conditions.

ADR-0020 sets the description shape (trigger + one capability +
boundary), two-tier size gates sitting below the unchanged
agentskills.io ceilings, a mandatory dispatch pattern for multi-branch
bodies, a Gotchas constraint, an agent-side delegation check, and
invocation as a design axis. Gates ship blocking with no baseline.

Adds five CONTEXT.md glossary entries: preload tax, skill context
contract, dispatch body, hand-invoked skill, delegation discipline.

Refs: ADR-0020
2026-08-14 19:39:14 +00:00