Skip to content

Commit c310972

Browse files
committed
Merge origin/main: renumber five colliding plugin releases
Main released its own ai-briefing 0.7.6, docs-hygiene 0.19.1, markdown-format 0.11.27, powershell-format 0.7.20, and claude-config 0.39.0 under the branch; ours renumber above them (0.7.7, 0.19.2, 0.11.28, 0.7.21, 0.39.1) with main's entries preserved. The merge resolver now collapses its double-blank artifact itself. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01REtnZ2hNpvRpfaL7venur5
2 parents 0b945fb + 1aff27e commit c310972

47 files changed

Lines changed: 2437 additions & 162 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.claude/source-control.md

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,26 @@ Commit-subject / PR-title convention for the source-control plugin, resolved by
55
CLAUDE.md/rules/commit-msg hook or fall back to the bundled Conventional Commits default.
66
Re-run `/source-control:setup` to change these values.
77

8-
Only `pr_body_required_sections` is set here — every other key falls through to
9-
`/source-control:setup`'s inference (this repo's commit history is already Conventional-Commits-shaped)
10-
per config-resolution.md's per-key fallthrough, so this file deliberately does not restate them.
8+
Of the convention keys, only `pr_body_required_sections` is set here — every other one falls through
9+
to `/source-control:setup`'s inference (this repo's commit history is already
10+
Conventional-Commits-shaped) per config-resolution.md's per-key fallthrough, so this file
11+
deliberately does not restate them. The `babysit_loop_*` keys below are the other key family this
12+
file carries, and they are set explicitly.
13+
14+
The `pr_body_required_sections` values below are the sections this repo's merge gate actually
15+
requires, each non-empty, alongside a native closing keyword: `pr-issue-linkage`, defined in
16+
`melodic-software/ci-workflows/.github/workflows/pr-issue-linkage.yml` and called by this repo's
17+
`.github/workflows/pr-issue-linkage.yml` — which exempts `dependabot[bot]`, and no other author. The
18+
gate is the authority; this key restates it so `/source-control:pull-request` drafts a body that
19+
passes. Read the reusable at the SHA the caller pins, not at its default branch, since that pin is
20+
what actually runs. Re-read it before changing either — an author or agent trusting a stale list
21+
writes a PR body that fails CI.
1122

1223
## pr_body_required_sections
1324

1425
- Summary
15-
- Test plan
26+
- Fix
27+
- Verification
1628
- Related
1729

1830
## babysit_loop_stop_mode

.github/workflows/ci.yml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1072,6 +1072,15 @@ jobs:
10721072
- name: Run affected-suite selector tests
10731073
if: steps.scope.outputs.docs_only != 'true'
10741074
run: bash scripts/affected-tests.test.sh
1075+
# Same reason again — run-plugin-tests.sh never reaches scripts/. This
1076+
# suite covers scripts/lib/changed-files.sh, the base-ref and changed-file
1077+
# resolver the checker gates share. Its NUL-safety cases are the invariant
1078+
# four of those gates had diverged on (#2914), and no caller suite
1079+
# exercises a C-quotable pathname, so this is the only place a regression
1080+
# there turns anything red.
1081+
- name: Run shared changed-file resolver tests
1082+
if: steps.scope.outputs.docs_only != 'true'
1083+
run: bash scripts/lib/changed-files.test.sh
10751084
- name: Validate plugin and catalog manifests
10761085
if: steps.scope.outputs.docs_only != 'true'
10771086
run: scripts/validate-plugins.sh

docs/MIGRATION-PLAYBOOK.md

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -306,8 +306,10 @@ a skill ships them only when they earn their keep.
306306
**Warrant rule.** A skill **warrants** evals when it carries a judgment-bearing behavioral contract
307307
that could silently regress — how it triggers, how it routes an ambiguous request, when it refuses,
308308
or the shape of what it emits. A skill is an explicit **skip** when it is pure-reference (answers
309-
from a knowledge corpus with no decision contract — `playbooks:fable-5`, `tdd`, …) or lives in a **hook** plugin
310-
(deterministic, silent-always-on, guarded by `.test.sh`, no model-invoked skill). A `setup`
309+
from a knowledge corpus with no decision contract — `playbooks:fable-5`, `tdd`, …). A **hook** plugin
310+
is a skip only in the case its rationale actually describes — deterministic, silent-always-on,
311+
guarded by `.test.sh`, **no model-facing skill at all**. A hook plugin that ships a `setup` skill has
312+
a skill with a judgment-bearing contract, and the plugin's shape does not exempt it: a `setup`
311313
skill *is* warrantable — it makes interview and write-config decisions (the
312314
`codebase-health/setup` eval is the model). Gray-zone skills (thin mechanical wrappers, reference-ish
313315
routers) are **author-confirm**: re-check the warrant against the live `SKILL.md` at authoring time
@@ -316,6 +318,19 @@ This section is the policy; current coverage is verified on demand — a live gl
316318
`plugins/*/skills/*/evals/evals.json` against the tree, read against the warrant rule above — never a
317319
checked-in snapshot that decays the moment a skill lands.
318320

321+
**The gate is operative, and it is broader than this policy.** `scripts/check-changed-skills.sh`
322+
passes `--require-evals` for every skill whose `SKILL.md` is new or modified, and
323+
`plugins/skill-quality/scripts/check-skill.sh` then hard-FAILs on a missing `evals/evals.json` for
324+
any skill shape — with no allowlist, frontmatter opt-out, or plugin-type awareness in either, and no
325+
way for the one CI caller to override it. So a "skip" verdict recorded here holds only until someone
326+
touches that `SKILL.md`, at which point CI requires evals and gets them. Read this policy as
327+
governing what a skill ships *absent a touch*, and expect the gate to decide otherwise the moment
328+
the file changes. That is a real disagreement rather than a nuance, and the pure-reference skip is
329+
where it still bites: the standing resolution — either the gate learns a recorded-skip mechanism
330+
(the repo's idiom is an exemptions file carrying the verdict, as
331+
`scripts/skill-count-claim-exemptions.txt` does) or this policy drops "skip" and evals become
332+
mandatory — is tracked in issue #3135 and is not settled here.
333+
319334
**Rich form.** Each case carries `id`, a kebab-case `name`, a `prompt`, an `expected_output`
320335
description, optional `files` fixtures, and an `expectations` array of objectively-verifiable checks
321336
(the field may equivalently be named `assertions` — skill-creator upstream uses that name). Aim to
@@ -1342,7 +1357,9 @@ Reintegration (below) covers a repo that already ran an in-repo copy and now swi
13421357
scope; a sensitive value still routes to secure credential storage (smoke-tests A and C).
13431358
Re-running that command later against an already-installed plugin prints `already installed`
13441359
**and still writes the value** (smoke-test C), so a headless reconfiguration is another `--config`
1345-
install rather than an uninstall/reinstall. Interactively, `/plugin configure` owns personal
1360+
install rather than an uninstall/reinstall — verified for a **non-sensitive option at `user`
1361+
scope** on Claude Code 2.1.240 and **not** at the `--scope project` this step uses, so read the
1362+
stored value back there rather than assuming the write landed. Interactively, `/plugin configure` owns personal
13461363
`userConfig`; an explicit setup skill owns any separate tracked project configuration declared by
13471364
the plugin.
13481365
4. **Headless prompting caveat.** Install never prompts non-interactively — a required `userConfig`
@@ -1392,7 +1409,12 @@ surface to a published plugin for a single consumer's low-value nicety.
13921409
project --config KEY=VALUE …`, seeding every
13931410
non-default `userConfig` toggle on that install command — re-running it later against an
13941411
already-installed plugin prints `already installed` **and still writes the value** (smoke-test C),
1395-
so a headless reconfiguration is another `--config` install, not an uninstall/reinstall.
1412+
so a headless reconfiguration is another `--config` install, not an uninstall/reinstall. That was
1413+
verified for a **non-sensitive option at `user` scope** on Claude Code 2.1.240 and is **untested at
1414+
the `project` scope this step uses**, so read the stored value back before reporting a
1415+
project-scope reconfiguration as applied — from the **user** `settings.json` `pluginConfigs`, where
1416+
step 3 above records non-sensitive options landing irrespective of enable scope (itself observed
1417+
only at `--scope local`, smoke-test A), not from the project settings this command names.
13961418
**Exception:** a `directory`/`file` relative-path entry in checked-in project settings resolves
13971419
against the repo checkout (cloud sessions included) — see
13981420
[`docs/CLOUD-SESSIONS.md`](CLOUD-SESSIONS.md). Otherwise the marketplace is known but the plugin is absent, and step 3's

docs/PLUGIN-PHILOSOPHY.md

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,30 @@ consumer tiers, explicit adoption — is owned by `melodic-software/standards`
1616
`conventions/engineering/shareable-artifact-design.md`; this document specializes it for Claude Code
1717
plugins and adds only what is plugin-specific.
1818

19+
**Org-agnosticism** names the publisher half of that boundary, and it governs *tokens in shipped
20+
content*, not only runtime behavior: the publishing organization's name, its marketplace id, its own
21+
repository names, and publisher-prefixed configuration keys do not appear in a plugin's skill, agent,
22+
or schema content. One use is sanctioned — a citation that *names a source rather than a target the
23+
plugin acts on*: a documentation URL, or a cross-plugin reference to this marketplace's own published
24+
files, cited for a reader to consult. The line is what the content does with it, not where it points:
25+
prose citing such a URL is conforming, while a skill instructed to fetch, poll, or write to it has
26+
made the publisher a runtime dependency and is not. (`plugin.json` publisher metadata sits outside
27+
this rule entirely, being neither skill, agent, nor schema content — identifying the source is what
28+
the manifest is for.)
29+
30+
Like the setup contract below, **this is a normative target, not a description of the fleet**, and
31+
enforcement reaches a strict subset of it. `scripts/validate-plugin-contracts.mjs` gates the
32+
marketplace id, `melodic-software/github-iac`, and `MELODIC_*` keys across every plugin's skill
33+
content, and holds the `autonomy` plugin to a stricter token set;
34+
`plugins/github/github.test.sh` runs a wider sweep over its own plugin's prose as its "agnostic
35+
conformance" check — a sibling of that file's D4 zero-vendored-knowledge checks, not one of them. The
36+
bare organization name in skill prose is gated nowhere *fleet-wide* — only inside `autonomy` and
37+
`github`, each by its own narrower sweep — and agent content is gated nowhere at all, so shipped
38+
skills predating this statement are nonconforming until brought into conformance rather than absolved
39+
by a green build. A fleet-wide edit answers to two independent mechanisms, both steps of the same
40+
`plugin-gate` CI job and neither aware of the other; consolidating them behind this statement, and
41+
settling that conformance gap deliberately, is tracked in issue #3136.
42+
1943
Keep plugins horizontally decoupled:
2044

2145
- A plugin owns its skills, hooks, agents, scripts, dependencies, and state.
@@ -367,9 +391,33 @@ is closed. Setup must be:
367391
- idempotent and safe to rerun;
368392
- transparent about what it inferred, changed, skipped, or could not verify;
369393
- limited to configuration the plugin owns;
370-
- safe for existing files, preserving unrelated user content; and
394+
- safe for existing files, preserving unrelated user content;
395+
- evidence-bearing: after making or routing a change, it reports the effective value it *observed*,
396+
and says plainly where it could not observe one — never an unobserved change; and
371397
- non-interactive when complete arguments are supplied, so automation and headless use remain possible.
372398

399+
The readback is a property of the `setup` skill, not of the `apply` verb: it belongs to whichever
400+
action made or routed the change, so a check-only skill (below) carries it in `check`. Where the
401+
change was routed to a surface setup may not write — Claude Code's native configuration flow, an
402+
edit left to the operator — the rule is unchanged.
403+
404+
**Keep two claims apart:** that the write was issued and stored, and how the *running* session
405+
behaves. They can legitimately disagree, so a naive readback reports false failures — and reporting
406+
one as a failed write is the specific error this clause exists to prevent. Verify the effective value
407+
by re-checking in a **fresh session**, and never claim an unobserved change. A same-session `check`
408+
therefore satisfies the bullet above by reporting what it observed *and* naming it as possibly stale,
409+
not by pretending the running session already reflects the write.
410+
411+
Two mechanisms are offered across the fleet as the reason the two diverge: that a `${user_config.*}`
412+
value is substituted into skill content at load, and that a hook's `CLAUDE_PLUGIN_OPTION_*` mirror
413+
comes from an environment fixed at session start. Both timings are **untested here**.
414+
[Smoke-test D](extensibility-contract-smoke-tests.md) records the rendered *result* in skill content
415+
on Claude Code 2.1.212, not when substitution happens; smoke-test B records only a negative on
416+
2.1.207, that a skill-spawned Bash subprocess receives no mirror at all, and sources the
417+
agent-content half of that seam to upstream spec rather than to an observation. The rule does not
418+
rest on either: a fresh-session re-check is correct whichever way they resolve, which is why it is
419+
the prescription and they are only the explanation.
420+
373421
Setup is one **plugin-level** `setup` skill, never a per-skill setup action. Setup granularity
374422
follows install granularity: a plugin installs and is configured as a unit, and its configuration
375423
surface — tracked project files, external prerequisites, `userConfig` — is plugin-scoped and

0 commit comments

Comments
 (0)