From 874bf06b183fa791ec118bad733511f7a17b31b7 Mon Sep 17 00:00:00 2001 From: Defame1297 Date: Fri, 14 Aug 2026 11:05:20 +0000 Subject: [PATCH] chore(apm): regenerate compiled manifests and content mirrors Output of apm pack, sync-plugin-content.sh --all and sync-marketplace-mirror.sh against this round's source changes. No file here is hand-edited. Carries the version bumps and marketplace owner.email into the compiled manifests, the disallowedTools frontmatter and doc corrections into the flat mirrors, and changes plugins/bin/.github/plugin/plugin.json's mcpServers from the inlined server object to the ".mcp.json" pointer. That last file also returns to 0644: the previous re-injection wrote it through mktemp and carried 0600 across, which no gate could see because the mode check did not cover .github/plugin/ and git tracks only the exec bit. .agents/plugins/marketplace.json is unchanged and that is correct -- apm's codex profile carries neither version nor owner keys, so nothing in this round reaches it. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01X7GvKuJfy2WrdBmUttV4DT --- .claude-plugin/marketplace.json | 12 ++++++---- .github/plugin/marketplace.json | 12 ++++++---- plugins/bin/.claude-plugin/plugin.json | 2 +- plugins/bin/.github/plugin/plugin.json | 13 ++--------- plugins/core/skills/agentsmd-audit/README.md | 13 +++++++---- .../skills/provider-adapter-author/README.md | 9 ++++++-- plugins/git/.claude-plugin/plugin.json | 2 +- plugins/git/.github/plugin/plugin.json | 2 +- plugins/gitea/.claude-plugin/plugin.json | 2 +- plugins/gitea/.github/plugin/plugin.json | 2 +- .../gitea/agents/gitea-orchestrate.agent.md | 6 +++-- .../agents/apm-orchestrate.agent.md | 7 ++++-- .../kyberforge/skills/agent-audit/README.md | 13 +++++++---- .../kyberforge/skills/agent-audit/SKILL.md | 4 ++-- .../agent-audit/references/field-inventory.md | 23 ++++++++++++++++++- .../skills/agent-audit/scripts/validate.sh | 11 +++++---- .../kyberforge/skills/agent-author/README.md | 12 ++++++++-- .../skills/agent-author/scripts/README.md | 2 +- .../kyberforge/skills/skill-audit/README.md | 11 ++++++--- .../kyberforge/skills/skill-author/README.md | 12 ++++++++-- plugins/lint/.claude-plugin/plugin.json | 2 +- plugins/lint/.github/plugin/plugin.json | 2 +- plugins/lint/agents/lint-runner.agent.md | 2 ++ 23 files changed, 119 insertions(+), 57 deletions(-) diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index f4d89fb..c28e71d 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -1,9 +1,10 @@ { "name": "holocron", "description": "AI development skills for Claude Code and GitHub Copilot CLI — factory, design, implement, review, and cross-cutting workflows.", - "version": "0.3.3", + "version": "0.3.4", "owner": { "name": "Defame1297", + "email": "defame1297@rkdr.net", "url": "https://git.dev.rkdr.net/Defame1297/" }, "plugins": [ @@ -17,21 +18,21 @@ { "name": "bin", "description": "A place for things to be binned", - "version": "1.1.1", + "version": "1.1.2", "category": "Utilities", "source": "./plugins/bin" }, { "name": "git", "description": "Skills for working with Git — conventional commits, branch management, pull requests, and feature flow.", - "version": "1.3.2", + "version": "1.3.3", "category": "Version Control", "source": "./plugins/git" }, { "name": "gitea", "description": "Skills for managing Gitea repositories — issues, pull requests, milestones, releases, and wikis.", - "version": "1.3.3", + "version": "1.3.4", "category": "Version Control", "source": "./plugins/gitea" }, @@ -45,6 +46,7 @@ { "name": "mattpocock-skills", "description": "Skills for Real Engineers — planning, TDD, architecture, and debugging workflows from Matt Pocock's .claude directory.", + "version": "1.2.3", "category": "Productivity", "source": { "source": "github", @@ -57,7 +59,7 @@ { "name": "lint", "description": "Skills and agents for configuring and running linters.", - "version": "1.1.5", + "version": "1.1.6", "category": "Developer Tools", "source": "./plugins/lint" } diff --git a/.github/plugin/marketplace.json b/.github/plugin/marketplace.json index f4d89fb..c28e71d 100644 --- a/.github/plugin/marketplace.json +++ b/.github/plugin/marketplace.json @@ -1,9 +1,10 @@ { "name": "holocron", "description": "AI development skills for Claude Code and GitHub Copilot CLI — factory, design, implement, review, and cross-cutting workflows.", - "version": "0.3.3", + "version": "0.3.4", "owner": { "name": "Defame1297", + "email": "defame1297@rkdr.net", "url": "https://git.dev.rkdr.net/Defame1297/" }, "plugins": [ @@ -17,21 +18,21 @@ { "name": "bin", "description": "A place for things to be binned", - "version": "1.1.1", + "version": "1.1.2", "category": "Utilities", "source": "./plugins/bin" }, { "name": "git", "description": "Skills for working with Git — conventional commits, branch management, pull requests, and feature flow.", - "version": "1.3.2", + "version": "1.3.3", "category": "Version Control", "source": "./plugins/git" }, { "name": "gitea", "description": "Skills for managing Gitea repositories — issues, pull requests, milestones, releases, and wikis.", - "version": "1.3.3", + "version": "1.3.4", "category": "Version Control", "source": "./plugins/gitea" }, @@ -45,6 +46,7 @@ { "name": "mattpocock-skills", "description": "Skills for Real Engineers — planning, TDD, architecture, and debugging workflows from Matt Pocock's .claude directory.", + "version": "1.2.3", "category": "Productivity", "source": { "source": "github", @@ -57,7 +59,7 @@ { "name": "lint", "description": "Skills and agents for configuring and running linters.", - "version": "1.1.5", + "version": "1.1.6", "category": "Developer Tools", "source": "./plugins/lint" } diff --git a/plugins/bin/.claude-plugin/plugin.json b/plugins/bin/.claude-plugin/plugin.json index 1bd8eab..18e4804 100644 --- a/plugins/bin/.claude-plugin/plugin.json +++ b/plugins/bin/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "bin", - "version": "1.1.1", + "version": "1.1.2", "description": "A place for things to be binned", "author": { "name": "Defame1297", diff --git a/plugins/bin/.github/plugin/plugin.json b/plugins/bin/.github/plugin/plugin.json index 1bd8eab..74e5109 100644 --- a/plugins/bin/.github/plugin/plugin.json +++ b/plugins/bin/.github/plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "bin", - "version": "1.1.1", + "version": "1.1.2", "description": "A place for things to be binned", "author": { "name": "Defame1297", @@ -17,14 +17,5 @@ "tdd", "research" ], - "mcpServers": { - "obsidian": { - "args": [ - "@bitbonsai/mcpvault@latest", - "docs/" - ], - "command": "npx", - "type": "stdio" - } - } + "mcpServers": ".mcp.json" } diff --git a/plugins/core/skills/agentsmd-audit/README.md b/plugins/core/skills/agentsmd-audit/README.md index 105a905..d863d94 100644 --- a/plugins/core/skills/agentsmd-audit/README.md +++ b/plugins/core/skills/agentsmd-audit/README.md @@ -24,7 +24,12 @@ Provide the path to the repo root to audit when invoking. | `scripts/validate-drift.sh` | Resolves referenced npm/make commands and file paths against the repo | | `references/sources.md` | Provenance record — sources that informed this skill and which files each contributed to | | `scripts/README.md` | Directory documentation for `scripts/` | -| `tests/README.md` | Bats test dependency and run instructions | -| `tests/validate-secrets.bats` | Bats test suite for `scripts/validate-secrets.sh` | -| `tests/validate-structure.bats` | Bats test suite for `scripts/validate-structure.sh` | -| `tests/validate-drift.bats` | Bats test suite for `scripts/validate-drift.sh` | +| `tests/README.md` | (source-only) Bats test dependency and run instructions | +| `tests/validate-secrets.bats` | (source-only) Bats test suite for `scripts/validate-secrets.sh` | +| `tests/validate-structure.bats` | (source-only) Bats test suite for `scripts/validate-structure.sh` | +| `tests/validate-drift.bats` | (source-only) Bats test suite for `scripts/validate-drift.sh` | + +Rows marked **(source-only)** exist in the authoring source (`.apm/skills/agentsmd-audit/`) but are +not present in an installed plugin: `scripts/sync-plugin-content.sh` strips `//tests` +when it generates the flat mirror, because these are dev-time fixtures no plugin host needs to +discover (ADR-0017). Run them from a repo checkout, not from an install. diff --git a/plugins/core/skills/provider-adapter-author/README.md b/plugins/core/skills/provider-adapter-author/README.md index ebd4fe2..9dc0652 100644 --- a/plugins/core/skills/provider-adapter-author/README.md +++ b/plugins/core/skills/provider-adapter-author/README.md @@ -26,5 +26,10 @@ Provide the path to the provider-specific file to convert (and the target repo r | `references/sources.md` | Provenance record — the in-repo ADR precedent this skill's design is modeled on | | `scripts/validate-adapter.sh` | Self-check gate: reference to AGENTS.md present, no excessive duplication, adapter stays thin | | `scripts/README.md` | Directory documentation for `scripts/` | -| `tests/README.md` | Bats test dependency and run instructions | -| `tests/validate-adapter.bats` | Bats test suite for `scripts/validate-adapter.sh` | +| `tests/README.md` | (source-only) Bats test dependency and run instructions | +| `tests/validate-adapter.bats` | (source-only) Bats test suite for `scripts/validate-adapter.sh` | + +Rows marked **(source-only)** exist in the authoring source (`.apm/skills/provider-adapter-author/`) +but are not present in an installed plugin: `scripts/sync-plugin-content.sh` strips +`//tests` when it generates the flat mirror, because these are dev-time fixtures no +plugin host needs to discover (ADR-0017). Run them from a repo checkout, not from an install. diff --git a/plugins/git/.claude-plugin/plugin.json b/plugins/git/.claude-plugin/plugin.json index e4b30b2..f394b25 100644 --- a/plugins/git/.claude-plugin/plugin.json +++ b/plugins/git/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "git", - "version": "1.3.2", + "version": "1.3.3", "description": "Skills for working with Git \u2014 conventional commits, branch management, pull requests, and feature flow.", "author": { "name": "Defame1297", diff --git a/plugins/git/.github/plugin/plugin.json b/plugins/git/.github/plugin/plugin.json index e4b30b2..f394b25 100644 --- a/plugins/git/.github/plugin/plugin.json +++ b/plugins/git/.github/plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "git", - "version": "1.3.2", + "version": "1.3.3", "description": "Skills for working with Git \u2014 conventional commits, branch management, pull requests, and feature flow.", "author": { "name": "Defame1297", diff --git a/plugins/gitea/.claude-plugin/plugin.json b/plugins/gitea/.claude-plugin/plugin.json index 8b8d916..61fa711 100644 --- a/plugins/gitea/.claude-plugin/plugin.json +++ b/plugins/gitea/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "gitea", - "version": "1.3.3", + "version": "1.3.4", "description": "Skills for managing Gitea repositories \u2014 issues, pull requests, milestones, releases, and wikis.", "author": { "name": "Defame1297", diff --git a/plugins/gitea/.github/plugin/plugin.json b/plugins/gitea/.github/plugin/plugin.json index 8b8d916..61fa711 100644 --- a/plugins/gitea/.github/plugin/plugin.json +++ b/plugins/gitea/.github/plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "gitea", - "version": "1.3.3", + "version": "1.3.4", "description": "Skills for managing Gitea repositories \u2014 issues, pull requests, milestones, releases, and wikis.", "author": { "name": "Defame1297", diff --git a/plugins/gitea/agents/gitea-orchestrate.agent.md b/plugins/gitea/agents/gitea-orchestrate.agent.md index 05ca1c5..45f93ce 100644 --- a/plugins/gitea/agents/gitea-orchestrate.agent.md +++ b/plugins/gitea/agents/gitea-orchestrate.agent.md @@ -9,9 +9,10 @@ source_keys: - context7-websites-gitea - context7-gitea-tea-cli +disallowedTools: Edit, Write, NotebookEdit --- -You are the orchestrator for the gitea plugin — a composable workflow dispatcher designed for other agents to invoke multi-step Gitea operations reliably. Your one job is routing and safety-gating: you do not call `mcp__gitea__*` tools yourself, you delegate to domain skills and enforce confirmation on destructive operations. +You are the orchestrator for the gitea plugin — a composable workflow dispatcher designed for other agents to invoke multi-step Gitea operations reliably. Your one job is routing and safety-gating: you do not call `mcp__gitea__*` tools yourself, you delegate to domain skills and enforce confirmation on destructive operations. You never edit files. Every write you cause reaches its target through a domain skill's Gitea API call — never through an edit you make to the local working tree. You resolve `owner`/`repo` once per session (via `git remote -v` on `origin`) and carry that forward as session context to every domain skill you dispatch to, rather than making each skill re-resolve it. @@ -28,6 +29,7 @@ These are non-negotiable regardless of `confirm` or any skill-local override: - Issues and PRs share one number space. Before dispatching an operation keyed on a bare number, resolve whether it's an issue or a PR yourself (see Number resolution) — never infer the domain from operation phrasing alone. - `list_releases`/`list_tags` default to `per_page: 20` (other domains default to 30) with no server-side auto-pagination — when a caller needs a complete result set, loop `page` upward until a page returns fewer than `per_page` results before returning. - Never commit secrets, credentials, or environment-specific config into any file written via `gitea-files`. +- You are read-only against the local working tree. Never create, edit, or delete a local file — not a manifest, not a config, not a scratch note. Local state is the caller's, and you only read it (e.g. `git remote -v`) to resolve context. ### Number resolution @@ -69,7 +71,7 @@ When invoked, you: 5. If the operation targets a bare number and the domain isn't specified, run Number resolution above before dispatch 6. Invoke the appropriate domain skill via `Skill` with the operation, parameters, and resolved context (`owner`, `repo`) 7. Catch and handle Gitea errors: disambiguate 404s (not-found vs. permission-hidden), retry transient failures, loop pagination for `list_releases`/`list_tags` until exhausted -8. If recovery succeeds, continue; if not, return error structure with diagnostics and suggestions +8. If recovery succeeds, continue; if not, return error structure with diagnostics and suggestions. If the blocker looks trivially fixable by a local edit — a stale `origin` URL, a malformed config, a missing label the repo obviously wants — name that fix in `suggestions` and stop. Do not act on it, and do not route it as a write operation the caller never asked for 9. Aggregate all outputs and return as structured JSON ## Output diff --git a/plugins/kyberforge/agents/apm-orchestrate.agent.md b/plugins/kyberforge/agents/apm-orchestrate.agent.md index ae6d836..3d135ad 100644 --- a/plugins/kyberforge/agents/apm-orchestrate.agent.md +++ b/plugins/kyberforge/agents/apm-orchestrate.agent.md @@ -5,9 +5,11 @@ description: Orchestrates apm package/marketplace operations for other agents. I source_keys: - context7-microsoft-apm + +disallowedTools: Edit, Write, NotebookEdit --- -You are the orchestrator for apm package/marketplace operations — a composable workflow dispatcher designed for other agents to invoke multi-step `apm` operations reliably, especially the same operation repeated across several packages in a monorepo-hybrid layout. Your one job is routing and safety-gating: you do not decide manifest content yourself, you delegate to `apm-workflow` and enforce confirmation on irreversible operations. +You are the orchestrator for apm package/marketplace operations — a composable workflow dispatcher designed for other agents to invoke multi-step `apm` operations reliably, especially the same operation repeated across several packages in a monorepo-hybrid layout. Your one job is routing and safety-gating: you do not decide manifest content yourself, you delegate to `apm-workflow` and enforce confirmation on irreversible operations. You never edit files. Every manifest or primitive that changes under your dispatch is written by `apm-workflow` or by `apm` itself — never by an edit you make. You resolve the package root once per dispatched operation (the directory containing that package's `apm.yml`) and carry it forward as session context rather than making every call re-resolve it. @@ -21,6 +23,7 @@ These are non-negotiable regardless of `confirm` or any skill-local override: - `apm.yml`'s `type:` field constrains what `.apm/` may contain — when scaffolding (`init-package`), set `type:` before any primitive content is added; do not defer it. - A clean plain `apm audit` is not a CI-equivalent pass — if the caller's intent is a CI gate, dispatch `audit-ci`, not `audit`. - Check the `apm experimental enable registries` precondition before dispatching any operation that depends on a named registry, and fail with a clear diagnostic rather than silently no-op'ing like apm itself does — see apm-workflow/SKILL.md Gotchas for the underlying constraint. +- You are read-only against the working tree. Never create, edit, or delete a file — not an `apm.yml`, not a `.apm/` primitive, not compiled output, not a scratch note. `edit-config` is an operation you *route* to `apm-workflow`, never one you perform: dispatching it is allowed only when the caller asked for that edit, never as your own repair of something you noticed. When invoked, you: 1. Parse the incoming workflow request (operation type, parameters, target package(s), context overrides) @@ -52,7 +55,7 @@ When invoked, you: 4. Verify `apm --version` succeeds; if not, fail with a diagnostic pointing to `apm-install` 5. Invoke `apm-workflow` via `Skill` with the resolved action, `package_root`, and parameters 6. If fanning across multiple packages, dispatch independent packages in parallel when no shared state or ordering dependency exists between them; loop package-by-package (strictly sequential) only for packages with a real dependency on another package's completion. Either way, collect per-package results and failures rather than aborting on the first failure -7. Catch and handle apm errors: retry once for a dependency-not-yet-scaffolded failure after the caller confirms the dependency exists; otherwise return error structure with diagnostics +7. Catch and handle apm errors: retry once for a dependency-not-yet-scaffolded failure after the caller confirms the dependency exists; otherwise return error structure with diagnostics. If the failure looks trivially fixable by a one-line manifest edit — a missing `category:`, a typo'd `source:`, a version that disagrees between a package and the catalog — name that fix in `suggestions` and stop. Do not apply it yourself and do not self-dispatch an `edit-config` to apply it 8. Aggregate all outputs and return as structured JSON ## Output diff --git a/plugins/kyberforge/skills/agent-audit/README.md b/plugins/kyberforge/skills/agent-audit/README.md index 6d9faa1..336e1a9 100644 --- a/plugins/kyberforge/skills/agent-audit/README.md +++ b/plugins/kyberforge/skills/agent-audit/README.md @@ -46,12 +46,17 @@ Pass the path to either agent file as the argument. | `assets/vale/styles/KyberforgeCopilot/ProactivePhrase.yml` | Flags CC-specific "Use proactively" phrasing with no effect in Copilot descriptions | | `references/README.md` | Directory documentation for references/ | | `references/description-quality.md` | Qualitative guide for borderline description findings | -| `references/field-inventory.md` | Authoritative list of valid CC and Copilot agent fields | +| `references/field-inventory.md` | Authoritative field lists read as data by `validate.sh`: valid CC and Copilot agent fields, and the vendor-neutral plugin/APM-scope allowlist | | `references/sources.md` | Research provenance for skill content | | `scripts/README.md` | Directory documentation for scripts/ | | `scripts/validate.sh` | Structural validation script for agent file pairs | | `scripts/validate-provenance.sh` | Provenance chain validation script for agent pairs against `sources.md` (plugin root) | | `scripts/vale-wrap.sh` | Drop-in `vale` wrapper that works around a frontmatter-description NLP scope limitation | -| `tests/README.md` | Bats test dependency and run instructions | -| `tests/validate.bats` | Bats tests for validate.sh | -| `tests/validate-provenance.bats` | Bats tests for validate-provenance.sh | +| `tests/README.md` | (source-only) Bats test dependency and run instructions | +| `tests/validate.bats` | (source-only) Bats tests for validate.sh | +| `tests/validate-provenance.bats` | (source-only) Bats tests for validate-provenance.sh | + +Rows marked **(source-only)** exist in the authoring source (`.apm/skills/agent-audit/`) but are +not present in an installed plugin: `scripts/sync-plugin-content.sh` strips +`//tests` when it generates the flat mirror, because these are dev-time fixtures no +plugin host needs to discover (ADR-0017). Run them from a repo checkout, not from an install. diff --git a/plugins/kyberforge/skills/agent-audit/SKILL.md b/plugins/kyberforge/skills/agent-audit/SKILL.md index 47db4ea..12f7c3b 100644 --- a/plugins/kyberforge/skills/agent-audit/SKILL.md +++ b/plugins/kyberforge/skills/agent-audit/SKILL.md @@ -44,13 +44,13 @@ The script accepts either the CC file, the Copilot file, or (at plugin/APM scope At **project/user scope** it derives the counterpart and runs the existing pair-based checks. Note FAILs and SUGGESTIONs for the `### Structure` and `### Provider safety` report dimensions. Findings about missing fields, bad name format, empty body, or missing frontmatter → `### Structure`. Findings about CC-only fields in a Copilot file, Copilot-only fields in a CC file, body length, or subagent-unavailable tools → `### Provider safety`. A missing counterpart file → `### Pair consistency`. -At **plugin/APM scope** there is no counterpart — the script instead checks the single file's frontmatter against the `apm-agent-allowlist` in `references/field-inventory.md` (`name`, `description`, `model`, `source_keys` — nothing else; `source_keys` is provenance metadata, not a provider-specific field, and is validated separately by `validate-provenance.sh` against `sources.md`). Findings about missing fields, bad name format, name/filename-stem mismatch, empty body, or missing frontmatter → `### Structure`, same as project/user scope. Findings about any field outside the allowlist (e.g. `tools`, or any Claude-only/Copilot-only field carried over from a hand-edit) and body length → `### Provider safety` — but the dimension's meaning shifts here: it is no longer a CC-vs-Copilot field-leakage check, it's a vendor-neutral-field-allowlist check, since `apm compile` verbatim-copies this file's frontmatter to every target and there is no per-target integrator to reconcile a CC-only or Copilot-only field (ADR-0016). `### Pair consistency` never applies at this scope — the script never emits a missing-counterpart FAIL here, because there is nothing to pair by design. +At **plugin/APM scope** there is no counterpart — the script instead checks the single file's frontmatter against the `apm-agent-allowlist` in `references/field-inventory.md`. Read that section for the current list rather than reciting one here; it is the authoritative source and it changes. As of 2026-08-14 it is `name`, `description`, `model`, `source_keys`, `disallowedTools` — `source_keys` is provenance metadata, not a provider-specific field, and is validated separately by `validate-provenance.sh` against `sources.md`; `disallowedTools` is a denylist, admitted because denying a tool by name is safe under `apm compile`'s verbatim copy in a way the `tools` allowlist is not (ADR-0016's 2026-08-14 amendment, and the rationale recorded alongside the list itself). Findings about missing fields, bad name format, name/filename-stem mismatch, empty body, or missing frontmatter → `### Structure`, same as project/user scope. Findings about any field outside the allowlist (e.g. `tools`, or any Claude-only/Copilot-only field carried over from a hand-edit) and body length → `### Provider safety` — but the dimension's meaning shifts here: it is no longer a CC-vs-Copilot field-leakage check, it's a vendor-neutral-field-allowlist check, since `apm compile` verbatim-copies this file's frontmatter to every target and there is no per-target integrator to reconcile a CC-only or Copilot-only field (ADR-0016). `### Pair consistency` never applies at this scope — the script never emits a missing-counterpart FAIL here, because there is nothing to pair by design. `vale-wrap.sh` ships inside this skill's own `scripts/` — resolve it relative to this skill's directory the same way `scripts/validate.sh` is resolved above, so the invocation works whether this skill is running from this repo or from an installed plugin cache. Pass no `--config`: handed none, the wrapper loads its own sibling `assets/vale/.vale.ini`, located from the script's path rather than from the cwd. Adding an explicit relative `--config` breaks exactly the case the self-location covers — a resolved script path plus an unresolved config path yields `E100 Runtime error ... does not exist`, exit 2, which the fallback below then misreads as "vale unavailable". At project/user scope, run it against both files of the pair (not just the one passed in); at plugin/APM scope, run it against the single file. `Kyberforge` applies to all of these files via the `**/agents/*.md` glob; `KyberforgeCopilot` applies to any `*.agent.md` file — including the plugin/APM-scope file, which already has that extension — via the `**/*.agent.md` glob, since its one rule (`Use proactively`) flags CC-specific phrasing that's meaningless in a vendor-neutral or Copilot description. Every Vale alert is a `FAIL` — all rules are graded `error` — so report each one in the `### Description` / `### Body` dimensions citing its rule ID (e.g. `KyberforgeCopilot.ProactivePhrase`). Skip and fall back to Step 2 judgment if the `vale` binary is unavailable. If Vale reports `0 files` scanned, treat the pass as NOT RUN — not as clean — and fall back to full Step 2 judgment for the dimensions it would have covered. `validate-provenance.sh` operates at plugin/APM scope only — it walks up from the agent file's directory the same way `validate.sh` does (nearest ancestor `apm.yml` with a top-level `type:` field; skip a `type:`-less marketplace-only `apm.yml`; stop at `.git` or the filesystem root) and exits 0 silently if that walk doesn't land on a package root, or when no provenance data exists. When it does apply, it validates the chain between the single file's own `source_keys` and the package-scoped `sources.md` (package root — see ADR-0010). Note FAILs from this script for the `### Provenance` dimension — surface them verbatim with Why and Fix. -If the scripts cannot run (Bash denied, python3 unavailable), perform checks manually. At project/user scope: counterpart file exists, required fields present (`name`, `description`, non-empty body), `name` is kebab-case, Copilot CLI `.agent.md` `name` must match filename stem (CC files are exempt — the CC platform does not require name to match filename), no `FILL IN:` placeholders, no CC-only fields in Copilot file, no Copilot-only fields in CC file (read `references/field-inventory.md` for the authoritative field lists). At plugin/APM scope: required fields present (`name`, `description`, non-empty body), `name` is kebab-case and matches the filename stem, no `FILL IN:` placeholders, no frontmatter field outside `name`/`description`/`model`/`source_keys` (read the `apm-agent-allowlist` section of `references/field-inventory.md`; `source_keys` carries provenance metadata, checked separately by `validate-provenance.sh` against `sources.md`). +If the scripts cannot run (Bash denied, python3 unavailable), perform checks manually. At project/user scope: counterpart file exists, required fields present (`name`, `description`, non-empty body), `name` is kebab-case, Copilot CLI `.agent.md` `name` must match filename stem (CC files are exempt — the CC platform does not require name to match filename), no `FILL IN:` placeholders, no CC-only fields in Copilot file, no Copilot-only fields in CC file (read `references/field-inventory.md` for the authoritative field lists). At plugin/APM scope: required fields present (`name`, `description`, non-empty body), `name` is kebab-case and matches the filename stem, no `FILL IN:` placeholders, no frontmatter field outside the allowlist — read the `apm-agent-allowlist` section of `references/field-inventory.md` for it, do not work from memory (`source_keys` carries provenance metadata, checked separately by `validate-provenance.sh` against `sources.md`). ## Step 2 — Qualitative checks diff --git a/plugins/kyberforge/skills/agent-audit/references/field-inventory.md b/plugins/kyberforge/skills/agent-audit/references/field-inventory.md index a23c48f..9f0a083 100644 --- a/plugins/kyberforge/skills/agent-audit/references/field-inventory.md +++ b/plugins/kyberforge/skills/agent-audit/references/field-inventory.md @@ -25,4 +25,25 @@ target disable-model-invocation user-invocable mcp-servers metadata ## apm-agent-allowlist -name description model source_keys +name description model source_keys disallowedTools + +Parsing note: `validate.sh` reads the **first** non-empty, non-`#`, non-`---` line under each +heading as a whitespace-separated token list, and stops there. Keep the token line immediately +below its heading; explanatory prose goes after it, as here. + +Why `disallowedTools` is on a list that is otherwise vendor-neutral, when `tools` is not +(ADR-0016 and its 2026-08-14 amendment): the two are not symmetric. `tools` is an **allowlist** +whose vocabulary differs per harness — Claude Code names its own tools, Copilot CLI uses aliases +(`execute`/`read`/`edit`/`search`/`agent`/`web`) — so a value correct for one is wrong for the +other, and `apm compile` copies frontmatter verbatim with no per-target integrator to reconcile +them. `disallowedTools` is a **denylist**, and denying by name is safe under verbatim copy: a name +the other harness does not recognise denies nothing, so the worst case is that the fence is absent +there, never that the wrong capability is granted. Claude Code honours it for plugin subagents — +`docs/research/docs/claude-code-plugins/agent-definition.md:99` names the fields plugin agents +silently ignore (`hooks`, `mcpServers`, `permissionMode`) and `disallowedTools` is not among them. + +`disallowedTools` also appears in `claude-code-only-fields` above, and that stays correct: at +project/user scope it is still a Claude-only field and must not appear in a Copilot `.agent.md`. +The two lists answer different questions — "may this field cross the CC/Copilot file boundary" for +a real pair, versus "is this field safe under verbatim copy to every target" for a single +vendor-neutral APM file. diff --git a/plugins/kyberforge/skills/agent-audit/scripts/validate.sh b/plugins/kyberforge/skills/agent-audit/scripts/validate.sh index 77a982f..6759140 100755 --- a/plugins/kyberforge/skills/agent-audit/scripts/validate.sh +++ b/plugins/kyberforge/skills/agent-audit/scripts/validate.sh @@ -241,10 +241,13 @@ def check_apm_agent_file(fpath, allowlist, stem): fail(f"frontmatter still contains template HTML comments () " f"— delete them before shipping — {local_fname}") - # Allowlist: only name/description/model may appear — no tools, no - # Claude-only or Copilot-only fields. apm compile verbatim-copies - # frontmatter to every target, so anything else is unsafe on at least - # one harness (ADR-0016). + # Allowlist: the permitted keys are data, read at load time from + # references/field-inventory.md's `## apm-agent-allowlist` section — do not + # restate them here, or this comment goes stale the next time that line + # changes. apm compile verbatim-copies frontmatter to every target, so a key + # outside the list is unsafe on at least one harness (ADR-0016). Note the + # list admits denylist-shaped restrictions (disallowedTools) but never + # allowlist-shaped ones (tools), whose value shape differs per harness. fm_keys = get_frontmatter_keys(fm) for key in sorted(fm_keys): if key not in allowlist: diff --git a/plugins/kyberforge/skills/agent-author/README.md b/plugins/kyberforge/skills/agent-author/README.md index 76fa208..f3c4de9 100644 --- a/plugins/kyberforge/skills/agent-author/README.md +++ b/plugins/kyberforge/skills/agent-author/README.md @@ -38,8 +38,16 @@ bash scripts/new-agent.sh security-reviewer ~ | `assets/templates/claude-code.md` | Annotated Claude Code agent definition template (project/user scope) | | `assets/templates/copilot.agent.md.template` | Annotated Copilot CLI agent definition template (project/user scope) | | `assets/templates/apm-agent.md` | Annotated vendor-neutral APM agent definition template (plugin/APM scope) | -| `tests/new-agent.bats` | bats tests for `scripts/new-agent.sh` | +| `tests/new-agent.bats` | (source-only) bats tests for `scripts/new-agent.sh` | | `assets/README.md` | Directory meta-documentation for assets/ | | `references/README.md` | Directory meta-documentation for references/ | | `scripts/README.md` | Directory meta-documentation for scripts/ | -| `tests/README.md` | bats dependency instructions and run command | +| `tests/README.md` | (source-only) bats dependency instructions and run command | + +Rows marked **(source-only)** exist in the authoring source (`.apm/skills/agent-author/`) but are +not present in an installed plugin: `scripts/sync-plugin-content.sh` strips +`//tests` when it generates the flat mirror, because these are dev-time fixtures no +plugin host needs to discover (ADR-0017). Run them from a repo checkout, not from an install. The +`assets/templates/` rows above are unaffected — the exclusion is depth-scoped to +`//tests`, so template trees that themselves contain a `tests/` directory ship +intact. diff --git a/plugins/kyberforge/skills/agent-author/scripts/README.md b/plugins/kyberforge/skills/agent-author/scripts/README.md index 32d891a..5017b0a 100644 --- a/plugins/kyberforge/skills/agent-author/scripts/README.md +++ b/plugins/kyberforge/skills/agent-author/scripts/README.md @@ -10,4 +10,4 @@ Usage: new-agent.sh Resolves scope by walking up from ``: a `type:`-bearing `apm.yml` found at or above `` → plugin/APM scope (single file at `/.apm/agents/.agent.md`; an `apm.yml` without `type:` is a marketplace-only manifest and is skipped); `` exactly `~` → user scope (`~/.claude/agents/` + `~/.copilot/agents/`); otherwise project scope (`/.claude/agents/` + `/.github/agents/`). Each file is a no-op if it already exists. See `--help` for full usage. -Tests: `tests/new-agent.bats` (requires `bats-support` and `bats-assert`). +Tests: `tests/new-agent.bats` (requires `bats-support` and `bats-assert`) — source-only. `scripts/sync-plugin-content.sh` strips `//tests` from the generated mirror (ADR-0017), so this file exists in a repo checkout of `.apm/skills/agent-author/` and not in an installed plugin. diff --git a/plugins/kyberforge/skills/skill-audit/README.md b/plugins/kyberforge/skills/skill-audit/README.md index 95b714e..27e5f38 100644 --- a/plugins/kyberforge/skills/skill-audit/README.md +++ b/plugins/kyberforge/skills/skill-audit/README.md @@ -33,6 +33,11 @@ Provide the path to the skill directory to audit when invoking. | `references/description-quality.md` | Spec-grounded rubric for description auditing — loaded when a finding is borderline | | `references/body-discipline.md` | Spec-grounded rubric for body discipline auditing — loaded when padding vs necessity is unclear | | `references/sources.md` | Provenance record — agentskills.io sources that informed this skill and which files each contributed to | -| `tests/validate.bats` | Bats test suite for validate.sh | -| `tests/validate-provenance.bats` | Bats test suite for validate-provenance.sh | -| `tests/README.md` | Setup instructions for bats-support and bats-assert test dependencies | +| `tests/validate.bats` | (source-only) Bats test suite for validate.sh | +| `tests/validate-provenance.bats` | (source-only) Bats test suite for validate-provenance.sh | +| `tests/README.md` | (source-only) Setup instructions for bats-support and bats-assert test dependencies | + +Rows marked **(source-only)** exist in the authoring source (`.apm/skills/skill-audit/`) but are +not present in an installed plugin: `scripts/sync-plugin-content.sh` strips +`//tests` when it generates the flat mirror, because these are dev-time fixtures no +plugin host needs to discover (ADR-0017). Run them from a repo checkout, not from an install. diff --git a/plugins/kyberforge/skills/skill-author/README.md b/plugins/kyberforge/skills/skill-author/README.md index 7eff92d..590ea33 100644 --- a/plugins/kyberforge/skills/skill-author/README.md +++ b/plugins/kyberforge/skills/skill-author/README.md @@ -46,8 +46,16 @@ If the destination resolves inside an APM package, read `references/deployment-m | `assets/templates/references/sources.md` | Sources provenance template for new skills | | `assets/templates/assets/README.md` | Placeholder for static assets | | `assets/templates/tests/README.md` | Placeholder for test files | -| `tests/new-skill.bats` | Bats test suite for `scripts/new-skill.sh` | -| `tests/README.md` | Setup instructions for bats-support and bats-assert test dependencies | +| `tests/new-skill.bats` | (source-only) Bats test suite for `scripts/new-skill.sh` | +| `tests/README.md` | (source-only) Setup instructions for bats-support and bats-assert test dependencies | + +Rows marked **(source-only)** exist in the authoring source (`.apm/skills/skill-author/`) but are +not present in an installed plugin: `scripts/sync-plugin-content.sh` strips +`//tests` when it generates the flat mirror, because these are dev-time fixtures no +plugin host needs to discover (ADR-0017). Run them from a repo checkout, not from an install. The +`assets/templates/tests/README.md` row above is **not** source-only — the exclusion is depth-scoped +to `//tests`, so the scaffolding template tree ships intact, which +`scripts/new-skill.sh` depends on at runtime. ## Spec reference diff --git a/plugins/lint/.claude-plugin/plugin.json b/plugins/lint/.claude-plugin/plugin.json index a48c48c..925ec0a 100644 --- a/plugins/lint/.claude-plugin/plugin.json +++ b/plugins/lint/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "lint", - "version": "1.1.5", + "version": "1.1.6", "description": "Skills and agents for configuring and running linters.", "author": { "name": "Defame1297", diff --git a/plugins/lint/.github/plugin/plugin.json b/plugins/lint/.github/plugin/plugin.json index a48c48c..925ec0a 100644 --- a/plugins/lint/.github/plugin/plugin.json +++ b/plugins/lint/.github/plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "lint", - "version": "1.1.5", + "version": "1.1.6", "description": "Skills and agents for configuring and running linters.", "author": { "name": "Defame1297", diff --git a/plugins/lint/agents/lint-runner.agent.md b/plugins/lint/agents/lint-runner.agent.md index 3b3ef60..d7ba8ab 100644 --- a/plugins/lint/agents/lint-runner.agent.md +++ b/plugins/lint/agents/lint-runner.agent.md @@ -5,6 +5,8 @@ description: Runs a linter sweep over a target file or directory scope and repor source_keys: - context7-websites-vale-sh + +disallowedTools: Edit, Write, NotebookEdit --- You are a linter runner. When invoked, you run the appropriate linter(s) over the requested scope, collect their findings, and report them back in a structured, reviewable form. You never edit files.