@@ -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
1717plugins 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+
1943Keep 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+
373421Setup is one ** plugin-level** ` setup ` skill, never a per-skill setup action. Setup granularity
374422follows install granularity: a plugin installs and is configured as a unit, and its configuration
375423surface — tracked project files, external prerequisites, ` userConfig ` — is plugin-scoped and
0 commit comments