From 40a045958fb2b3a6ffd683b74eb8d2ca12cc4348 Mon Sep 17 00:00:00 2001 From: Defame1297 Date: Thu, 23 Jul 2026 17:06:48 +0000 Subject: [PATCH 1/9] feat(core): add agentsmd-audit skill MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Audits a target repo's AGENTS.md file(s) for embedded secrets, structural completeness against the agents.md common-sections checklist, and drift (referenced commands/paths that no longer resolve). First active skill in the core plugin — kyberforge is scoped to marketplace-factory meta-tooling, not generic target-repo documentation (see ADR-0012). Moves the agentsmd research corpus from plugins/kyberforge to plugins/core to match. Co-Authored-By: Claude Sonnet 5 --- .../docs/research/docs/agentsmd/configuration.md | 0 .../{kyberforge => core}/docs/research/docs/agentsmd/examples.md | 0 .../{kyberforge => core}/docs/research/docs/agentsmd/overview.md | 0 .../{kyberforge => core}/docs/research/docs/agentsmd/sources.md | 0 4 files changed, 0 insertions(+), 0 deletions(-) rename plugins/{kyberforge => core}/docs/research/docs/agentsmd/configuration.md (100%) rename plugins/{kyberforge => core}/docs/research/docs/agentsmd/examples.md (100%) rename plugins/{kyberforge => core}/docs/research/docs/agentsmd/overview.md (100%) rename plugins/{kyberforge => core}/docs/research/docs/agentsmd/sources.md (100%) diff --git a/plugins/kyberforge/docs/research/docs/agentsmd/configuration.md b/plugins/core/docs/research/docs/agentsmd/configuration.md similarity index 100% rename from plugins/kyberforge/docs/research/docs/agentsmd/configuration.md rename to plugins/core/docs/research/docs/agentsmd/configuration.md diff --git a/plugins/kyberforge/docs/research/docs/agentsmd/examples.md b/plugins/core/docs/research/docs/agentsmd/examples.md similarity index 100% rename from plugins/kyberforge/docs/research/docs/agentsmd/examples.md rename to plugins/core/docs/research/docs/agentsmd/examples.md diff --git a/plugins/kyberforge/docs/research/docs/agentsmd/overview.md b/plugins/core/docs/research/docs/agentsmd/overview.md similarity index 100% rename from plugins/kyberforge/docs/research/docs/agentsmd/overview.md rename to plugins/core/docs/research/docs/agentsmd/overview.md diff --git a/plugins/kyberforge/docs/research/docs/agentsmd/sources.md b/plugins/core/docs/research/docs/agentsmd/sources.md similarity index 100% rename from plugins/kyberforge/docs/research/docs/agentsmd/sources.md rename to plugins/core/docs/research/docs/agentsmd/sources.md -- 2.43.0 From 6c8ea8e8f02a4c938a25c5986b64504515a017c4 Mon Sep 17 00:00:00 2001 From: Defame1297 Date: Thu, 23 Jul 2026 17:08:19 +0000 Subject: [PATCH 2/9] feat(core): add agentsmd-audit skill files MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The previous commit only landed the research-folder rename — a multi-path git add silently failed and left CONTEXT.md, ADR-0012, and the actual skill files unstaged. This lands them: the agentsmd-audit skill itself (three deterministic validators for secrets, structure, and drift against a target repo's AGENTS.md), its bats test suite, provenance record, and the CONTEXT.md/ADR entries documenting why this lives in core rather than kyberforge. Co-Authored-By: Claude Sonnet 5 --- CONTEXT.md | 6 + .../0012-agentsmd-tooling-in-core-plugin.md | 16 ++ plugins/core/skills/agentsmd-audit/README.md | 28 ++++ plugins/core/skills/agentsmd-audit/SKILL.md | 68 +++++++++ .../agentsmd-audit/references/sources.md | 33 +++++ .../skills/agentsmd-audit/scripts/README.md | 11 ++ .../agentsmd-audit/scripts/validate-drift.sh | 137 ++++++++++++++++++ .../scripts/validate-secrets.sh | 120 +++++++++++++++ .../scripts/validate-structure.sh | 118 +++++++++++++++ .../skills/agentsmd-audit/tests/README.md | 30 ++++ .../agentsmd-audit/tests/validate-drift.bats | 105 ++++++++++++++ .../tests/validate-secrets.bats | 68 +++++++++ .../tests/validate-structure.bats | 76 ++++++++++ 13 files changed, 816 insertions(+) create mode 100644 docs/adr/0012-agentsmd-tooling-in-core-plugin.md create mode 100644 plugins/core/skills/agentsmd-audit/README.md create mode 100644 plugins/core/skills/agentsmd-audit/SKILL.md create mode 100644 plugins/core/skills/agentsmd-audit/references/sources.md create mode 100644 plugins/core/skills/agentsmd-audit/scripts/README.md create mode 100755 plugins/core/skills/agentsmd-audit/scripts/validate-drift.sh create mode 100755 plugins/core/skills/agentsmd-audit/scripts/validate-secrets.sh create mode 100755 plugins/core/skills/agentsmd-audit/scripts/validate-structure.sh create mode 100644 plugins/core/skills/agentsmd-audit/tests/README.md create mode 100644 plugins/core/skills/agentsmd-audit/tests/validate-drift.bats create mode 100644 plugins/core/skills/agentsmd-audit/tests/validate-secrets.bats create mode 100644 plugins/core/skills/agentsmd-audit/tests/validate-structure.bats diff --git a/CONTEXT.md b/CONTEXT.md index 54b4c69..af6efa6 100644 --- a/CONTEXT.md +++ b/CONTEXT.md @@ -60,5 +60,11 @@ The three-stage traceability record linking a skill back to its research inputs: ### Bidirectional reference principle Files that reference other files should declare those references explicitly. The referencing file carries the forward reference (e.g. content index in `CLAUDE.md`, `references:` in frontmatter). The referenced file carries a `when:` field describing when it is loaded. Both sides should agree — divergence signals staleness. The reverse map ("what files reference this file?") is derived by a reference scanner script, not maintained manually. This principle applies to instruction files, skills, and workflow documents. +### agentsmd-author / agentsmd-audit +A skill pair in the `core` plugin for writing, updating, and reviewing a target repo's `AGENTS.md` file(s) (the generic open-standard file — see the `AGENTS.md` entry above — not this repo's own). `agentsmd-author` creates/updates AGENTS.md content, supports nested monorepo placement (per the standard's nearest-file-wins precedence), and closes out by invoking `agentsmd-audit` inline. `agentsmd-audit` runs a single combined pass checking three mandatory baselines: secrets/credentials (governance.md hard prohibition — AGENTS.md is committed content), structural completeness (common-sections checklist from the agents.md spec), and accuracy/drift (do referenced commands and paths actually resolve against the repo). `agentsmd-audit` never inspects provider adapter files (see `provider-adapter-author`) — its scope is AGENTS.md content only. Chosen over folding this into `kyberforge` because kyberforge's scope is meta-tooling for the holocron marketplace itself, not generic target-repo documentation; `core` is the intended home for cross-cutting, repo-agnostic utility skills. + +### provider-adapter-author +A companion skill (`core` plugin) that detects a target repo's provider-specific instruction file (`CLAUDE.md`, `.cursor/rules/*.mdc`, `copilot-instructions.md`, etc.) and, where it duplicates content AGENTS.md should own, converts it into a thin adapter that imports AGENTS.md — mirroring this repo's own ADR-0012 pattern. Self-validates via its own bundled deterministic script (`scripts/validate-adapter.sh`: checks for an import reference, no duplicated headings, size threshold) rather than a separate paired audit skill — the check is mechanical, so a script suffices per governance.md's "prefer deterministic code for repeatable tasks." `agentsmd-author` calls this skill via skill composition when it detects an existing provider file with overlapping content. + ### LESSONS.md Long-loop feedback log for patterns observed across sessions. Three or more entries on the same pattern graduate to the relevant standing file (e.g. a coding convention, a governance rule). Updated by the session-handoff skill or directly by the human. Lives at the repo root. diff --git a/docs/adr/0012-agentsmd-tooling-in-core-plugin.md b/docs/adr/0012-agentsmd-tooling-in-core-plugin.md new file mode 100644 index 0000000..eac8b90 --- /dev/null +++ b/docs/adr/0012-agentsmd-tooling-in-core-plugin.md @@ -0,0 +1,16 @@ +# AGENTS.md tooling lives in `core`, split into three skills + +`kyberforge` is scoped to meta-tooling for building and maintaining the holocron marketplace itself (skills, agents, plugins, marketplace entries) — not to generic capabilities for an arbitrary target repo. Authoring and reviewing a target repo's `AGENTS.md` file is repo-agnostic documentation tooling, closer in kind to `bin:write-docs` or `bin:init` than to `skill-author`/`plugin-author`. Research for this topic was initially placed under `plugins/kyberforge/docs/research/docs/agentsmd/` but has moved to `plugins/core/docs/research/docs/agentsmd/` to keep the provenance chain consistent with the plugin the resulting skills live in. + +## Decision + +Three skills in the `core` plugin (`core`'s first active skills): + +- **`agentsmd-author`** — creates/updates a target repo's `AGENTS.md`, including nested monorepo placement (nearest-file-wins). Closes out by invoking `agentsmd-audit` inline, mirroring the `skill-author`/`skill-audit` pattern. When it detects an existing provider-specific file (`CLAUDE.md`, etc.) with content that duplicates what AGENTS.md should own, it calls `provider-adapter-author` via skill composition. +- **`agentsmd-audit`** — a single combined pass checking three mandatory baselines against `AGENTS.md` only: secrets/credentials (governance.md hard prohibition), structural completeness (common-sections checklist from the agents.md spec), and accuracy/drift (do referenced commands/paths resolve against the repo). Never inspects provider adapter files. +- **`provider-adapter-author`** — detects and converts a provider-specific instruction file into a thin adapter that imports `AGENTS.md` (mirroring this repo's own two-tier `CLAUDE.md` pattern). Self-validates via its own bundled deterministic script (`scripts/validate-adapter.sh`) rather than a separate paired audit skill, since the check (import present, no duplicated headings, size threshold) is mechanical. + +## Consequences + +- `core`'s plugin.json/README will list real skills for the first time. +- `plugins/kyberforge/docs/research/docs/agentsmd/` moves to `plugins/core/docs/research/docs/agentsmd/` before authoring begins. diff --git a/plugins/core/skills/agentsmd-audit/README.md b/plugins/core/skills/agentsmd-audit/README.md new file mode 100644 index 0000000..8dfb3e6 --- /dev/null +++ b/plugins/core/skills/agentsmd-audit/README.md @@ -0,0 +1,28 @@ +# agentsmd-audit + +Audit a target repo's AGENTS.md file(s) for embedded secrets, structural completeness, and drift. + +## What it does + +Runs a single combined pass across every AGENTS.md file in a repo (root and any nested monorepo files): flags embedded secrets/credentials, checks structure against the agents.md common-sections checklist, and resolves referenced commands/paths against the actual repo to catch stale documentation. Outputs a compact findings report — findings only, grouped by dimension, each with Why and Fix. Never inspects provider-specific adapter files (CLAUDE.md, etc.) and never writes or fixes anything. + +## Usage + +``` +/agentsmd-audit +``` + +Provide the path to the repo root to audit when invoking. + +## Files + +| File | Purpose | +|------|---------| +| `SKILL.md` | Skill instructions for agents | +| `scripts/validate-secrets.sh` | Scans AGENTS.md files for embedded secrets, API keys, tokens, connection strings | +| `scripts/validate-structure.sh` | Checks for empty/placeholder content, common-sections checklist, nested-vs-root duplication | +| `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 | +| `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` | diff --git a/plugins/core/skills/agentsmd-audit/SKILL.md b/plugins/core/skills/agentsmd-audit/SKILL.md new file mode 100644 index 0000000..c873582 --- /dev/null +++ b/plugins/core/skills/agentsmd-audit/SKILL.md @@ -0,0 +1,68 @@ +--- +name: agentsmd-audit +description: > + Use when the user wants to review a repo's AGENTS.md file, says "audit this + AGENTS.md", "check my AGENTS.md", "is this AGENTS.md any good", or wants to + know if AGENTS.md is safe to commit — even if they don't use the word + "audit". Also invoke proactively after agentsmd-author creates or updates + AGENTS.md, or after a hand-edit made outside agentsmd-author. Audits a + target repo's AGENTS.md file(s) — root and any nested monorepo files — for + embedded secrets/credentials, structural completeness against the + agents.md common-sections checklist, and drift (referenced commands or + paths that no longer resolve against the repo). Produces a compact + findings report (findings only, no PASS noise) with Why and Fix per + finding. Do not use to audit CLAUDE.md, .cursor/rules, or other + provider-specific adapter files — that's provider-adapter-author's + self-contained concern. Do not use to fix or write AGENTS.md content — use + agentsmd-author instead. +allowed-tools: Bash Read +metadata: + category: docs + source_keys: + - agents-md-official + - context7-websites-agents-md + - context7-agentsmd-agents-md + - governance-secrets-hard-prohibition + version: "0.1.0" +--- + +## Gotchas + +- Always run all three checks — this skill does a single combined pass, not staged/gated passes. Don't skip structure or drift checks just because a secrets FAIL was found. +- Never inspect or mention provider-specific adapter files (`CLAUDE.md`, `.cursor/rules/*.mdc`, `copilot-instructions.md`, etc.) — that's out of scope. If one exists and duplicates AGENTS.md content, that's `provider-adapter-author`'s concern, not this skill's. +- A missing common section (e.g. no "Security" heading) is informational, not a failure — not every repo needs every section from the checklist. Only flag a FAIL when the file is empty, entirely unfilled placeholder text, or contains a real embedded secret/stale reference. +- Gather findings internally; don't narrate PASS/FAIL per check as you go — surface them only in the final report. + +## Step 1 — Run the validators + +```bash +bash scripts/validate-secrets.sh +bash scripts/validate-structure.sh +bash scripts/validate-drift.sh +``` + +Each script walks the repo for every `AGENTS.md` file (root and nested, excluding `.git`, `node_modules`, `vendor`, and similar) and prints `FAIL`/`INFO`/`SUGGESTION` lines with `Why`/`Fix` (or `Note`) per finding. A nonzero exit means at least one FAIL was found in that dimension. If a script cannot execute (`python3` unavailable, Bash denied), fall back to manual review: scan for real-looking credentials, check common sections are present, and spot-check a few referenced commands/paths by hand. + +## Step 2 — Report + +Open with a coverage line: + +```text +Checked: secrets · structure · drift +``` + +Then output only findings that were found, in this order within a repo: `### Secrets`, `### Structure`, `### Drift`. Omit a dimension heading entirely if it produced nothing — its absence confirms it passed. Report each finding verbatim as emitted by the scripts (they already carry file:line, Why/Fix or Note). + +Close with a result block: + +```text +## Result + +PASS +PASS · P info +PASS (N suggestions) · P info +FAIL (N fails) +FAIL (N fails) · P info +``` + +INFO and SUGGESTION findings are observational — they never flip PASS to FAIL. Do not fix anything — this skill reports and proposes only. Point the user to `agentsmd-author` to apply fixes. diff --git a/plugins/core/skills/agentsmd-audit/references/sources.md b/plugins/core/skills/agentsmd-audit/references/sources.md new file mode 100644 index 0000000..dfd3d9a --- /dev/null +++ b/plugins/core/skills/agentsmd-audit/references/sources.md @@ -0,0 +1,33 @@ +# Sources + +## agents-md-official + +- **URL:** https://agents.md/ +- **Description:** Official agents.md website — format spec, common-sections checklist, precedence rules (nearest-file-wins, no merge across files), monorepo nesting patterns +- **Research doc:** plugins/core/docs/research/docs/agentsmd/sources.md +- **Contributing files:** SKILL.md +- **Status:** `extracted` + +## context7-websites-agents-md + +- **URL:** context7:/websites/agents_md +- **Description:** Context7 index of the official agents.md website — overview, governance, cross-tool compatibility, configuration examples +- **Research doc:** plugins/core/docs/research/docs/agentsmd/sources.md +- **Contributing files:** SKILL.md +- **Status:** `extracted` + +## context7-agentsmd-agents-md + +- **URL:** context7:/agentsmd/agents.md +- **Description:** Context7 index of the agentsmd/agents.md repository — format spec, nested monorepo patterns, file structure examples +- **Research doc:** plugins/core/docs/research/docs/agentsmd/sources.md +- **Contributing files:** SKILL.md +- **Status:** `extracted` + +## governance-secrets-hard-prohibition + +- **URL:** (org convention — not a plugin research corpus entry) +- **Description:** Hard prohibition on placing secrets, API keys, tokens, or credentials in code, config, prompts, or any output. Grounds the secrets/credentials check in `scripts/validate-secrets.sh` and Step 1 of SKILL.md — AGENTS.md is committed content, so an embedded real secret is a hard-prohibition violation, not a style nit. +- **Research doc:** core/instructions/governance.md (org convention file, not a plugin research corpus entry; content is inlined here since plugins must be self-contained and this file may not exist wherever the plugin is installed) +- **Contributing files:** SKILL.md +- **Status:** `extracted` diff --git a/plugins/core/skills/agentsmd-audit/scripts/README.md b/plugins/core/skills/agentsmd-audit/scripts/README.md new file mode 100644 index 0000000..b05c3e7 --- /dev/null +++ b/plugins/core/skills/agentsmd-audit/scripts/README.md @@ -0,0 +1,11 @@ +# scripts/ + +Deterministic validators this skill shells out to instead of relying on LLM judgment for mechanical checks. + +| File | Purpose | +|------|---------| +| `validate-secrets.sh` | Scans every AGENTS.md file (root + nested) for embedded secrets, API keys, tokens, and connection strings | +| `validate-structure.sh` | Checks for empty/placeholder content, the common-sections checklist, and nested-vs-root duplication | +| `validate-drift.sh` | Resolves referenced npm/make commands and file paths against the actual repo state | + +All three take a single `` argument, print `FAIL`/`INFO`/`SUGGESTION` findings to stdout, and exit non-zero only on FAIL. diff --git a/plugins/core/skills/agentsmd-audit/scripts/validate-drift.sh b/plugins/core/skills/agentsmd-audit/scripts/validate-drift.sh new file mode 100755 index 0000000..14a0864 --- /dev/null +++ b/plugins/core/skills/agentsmd-audit/scripts/validate-drift.sh @@ -0,0 +1,137 @@ +#!/usr/bin/env bash +set -euo pipefail + +usage() { + cat < + +Check every AGENTS.md file in a repo (root and nested) for drift: package +manager scripts and file paths referenced in the text that no longer exist +in the repo. Catches the failure mode that matters most in practice — an +agent running a documented command that was renamed or deleted. + +Arguments: + repo-root Path to the repository root to scan. + +Exit codes: + 0 No FAIL findings (INFO may still be printed, e.g. no package.json found) + 1 One or more FAIL findings +EOF +} + +if [[ "${1:-}" == "--help" || "${1:-}" == "-h" ]]; then + usage + exit 0 +fi + +if [[ $# -lt 1 ]]; then + echo "Error: repo-root is required." >&2 + echo "" >&2 + usage >&2 + exit 1 +fi + +python3 -u - "$1" <<'PYTHON' +import sys +import os +import re +import json + +repo_root = os.path.abspath(sys.argv[1]) +if not os.path.isdir(repo_root): + print(f"Error: '{repo_root}' is not a directory.", file=sys.stderr) + sys.exit(1) + +EXCLUDE_DIRS = {".git", "node_modules", "vendor", ".venv", "venv", "dist", "build"} + +def find_agents_md(root): + results = [] + for dirpath, dirnames, filenames in os.walk(root): + dirnames[:] = [d for d in dirnames if d not in EXCLUDE_DIRS and not d.startswith(".")] + for fname in filenames: + if fname == "AGENTS.md": + results.append(os.path.join(dirpath, fname)) + return sorted(results) + +def load_package_scripts(root): + pkg_path = os.path.join(root, "package.json") + if not os.path.isfile(pkg_path): + return None + try: + with open(pkg_path, encoding="utf-8") as f: + data = json.load(f) + except (json.JSONDecodeError, OSError): + return None + return set(data.get("scripts", {}).keys()) + +def load_make_targets(root): + make_path = os.path.join(root, "Makefile") + if not os.path.isfile(make_path): + return None + with open(make_path, encoding="utf-8", errors="replace") as f: + content = f.read() + return set(re.findall(r'(?m)^([a-zA-Z0-9_-]+)\s*:(?!=)', content)) + +NPM_RUN_RE = re.compile(r'\b(?:npm|pnpm|yarn)\s+run\s+([a-zA-Z0-9:_-]+)') +MAKE_RE = re.compile(r'\bmake\s+([a-zA-Z0-9_-]+)') + +# Backticked relative file paths, e.g. `scripts/bootstrap.sh`, `src/index.ts`. +# Requires a path separator and file extension to avoid matching bare commands/words. +PATH_RE = re.compile(r'`([A-Za-z0-9_.\-]+(?:/[A-Za-z0-9_.\-]+)+\.[A-Za-z0-9]+)`') + +has_fail = False + +package_scripts = load_package_scripts(repo_root) +make_targets = load_make_targets(repo_root) + +for fpath in find_agents_md(repo_root): + rel = os.path.relpath(fpath, repo_root) + with open(fpath, encoding="utf-8", errors="replace") as f: + content = f.read() + + for m in NPM_RUN_RE.finditer(content): + script_name = m.group(1) + if package_scripts is None: + print(f"INFO Cannot verify referenced script '{script_name}' — {rel}") + print(f" Note: AGENTS.md references an npm/pnpm/yarn script, but no package.json was found at the repo root to check it against.") + print() + elif script_name not in package_scripts: + has_fail = True + print(f"FAIL Referenced script '{script_name}' not found in package.json — {rel}") + print(f" Why: AGENTS.md tells agents to run '{script_name}', but package.json has no matching \"scripts\" entry — the command will fail.") + print(f" Fix: Update AGENTS.md to reference an existing script, or add '{script_name}' to package.json's scripts.") + print() + + for m in MAKE_RE.finditer(content): + target_name = m.group(1) + if make_targets is None: + print(f"INFO Cannot verify referenced make target '{target_name}' — {rel}") + print(f" Note: AGENTS.md references a make target, but no Makefile was found at the repo root to check it against.") + print() + elif target_name not in make_targets: + has_fail = True + print(f"FAIL Referenced make target '{target_name}' not found in Makefile — {rel}") + print(f" Why: AGENTS.md tells agents to run 'make {target_name}', but the Makefile has no matching target — the command will fail.") + print(f" Fix: Update AGENTS.md to reference an existing target, or add '{target_name}' to the Makefile.") + print() + + file_dir = os.path.dirname(fpath) + for m in PATH_RE.finditer(content): + candidate = m.group(1) + resolved = ( + os.path.isfile(os.path.join(repo_root, candidate)) + or os.path.isfile(os.path.join(file_dir, candidate)) + or os.path.isdir(os.path.join(repo_root, candidate)) + or os.path.isdir(os.path.join(file_dir, candidate)) + ) + if not resolved: + has_fail = True + print(f"FAIL Referenced path '{candidate}' does not exist — {rel}") + print(f" Why: AGENTS.md points agents to '{candidate}', but it isn't present in the repo (checked relative to repo root and to the AGENTS.md's own directory).") + print(f" Fix: Update AGENTS.md to reference the correct path, or restore/create '{candidate}'.") + print() + +if has_fail: + sys.exit(1) +sys.exit(0) +PYTHON diff --git a/plugins/core/skills/agentsmd-audit/scripts/validate-secrets.sh b/plugins/core/skills/agentsmd-audit/scripts/validate-secrets.sh new file mode 100755 index 0000000..c8cb2f0 --- /dev/null +++ b/plugins/core/skills/agentsmd-audit/scripts/validate-secrets.sh @@ -0,0 +1,120 @@ +#!/usr/bin/env bash +set -euo pipefail + +usage() { + cat < + +Scan every AGENTS.md file in a repo (root and nested) for embedded secrets, +API keys, tokens, or connection strings. AGENTS.md is committed content — +real credentials in it are a hard-prohibition violation, not a style nit. +Placeholders (, \$ENV_VAR, YOUR_TOKEN_HERE, example.com, etc.) are +not flagged. + +Arguments: + repo-root Path to the repository root to scan. + +Exit codes: + 0 No findings + 1 One or more FAIL findings +EOF +} + +if [[ "${1:-}" == "--help" || "${1:-}" == "-h" ]]; then + usage + exit 0 +fi + +if [[ $# -lt 1 ]]; then + echo "Error: repo-root is required." >&2 + echo "" >&2 + usage >&2 + exit 1 +fi + +python3 -u - "$1" <<'PYTHON' +import sys +import os +import re + +repo_root = os.path.abspath(sys.argv[1]) +if not os.path.isdir(repo_root): + print(f"Error: '{repo_root}' is not a directory.", file=sys.stderr) + sys.exit(1) + +EXCLUDE_DIRS = {".git", "node_modules", "vendor", ".venv", "venv", "dist", "build"} + +def find_agents_md(root): + results = [] + for dirpath, dirnames, filenames in os.walk(root): + dirnames[:] = [d for d in dirnames if d not in EXCLUDE_DIRS and not d.startswith(".")] + for fname in filenames: + if fname == "AGENTS.md": + results.append(os.path.join(dirpath, fname)) + return sorted(results) + +PLACEHOLDER_RE = re.compile( + r'(?i)(your[_-]|my[_-]|example|xxx+|placeholder|changeme|<[^>]+>|\$\{|\$[A-Z_][A-Z0-9_]*|\.\.\.|redacted)' +) + +PATTERNS = [ + ("AWS access key ID", re.compile(r'AKIA[0-9A-Z]{16}')), + ("Private key block", re.compile(r'-----BEGIN [A-Z ]*PRIVATE KEY-----')), + ("GitHub token", re.compile(r'gh[pousr]_[A-Za-z0-9]{36,}')), + ("Slack token", re.compile(r'xox[baprs]-[A-Za-z0-9-]{10,}')), + ("GitLab token", re.compile(r'glpat-[A-Za-z0-9_-]{20,}')), + ("Generic API-style secret token", re.compile(r'\bsk-[A-Za-z0-9]{20,}\b')), + ( + "Credential-bearing connection string", + re.compile(r'[a-zA-Z][a-zA-Z0-9+.-]*://[^:@/\s]+:[^@/\s]+@[^\s\'"]+'), + ), + ( + "Assigned secret/password/token literal", + re.compile( + r'(?i)\b(api[_-]?key|secret|token|password|passwd|pwd|access[_-]?key)\b' + r'\s*[:=]\s*[\'"]?([A-Za-z0-9+/_.\-]{12,})[\'"]?' + ), + ), +] + +findings = [] + +def emit_fail(desc, fpath, lineno, why, fix): + findings.append((desc, fpath, lineno, why, fix)) + +for fpath in find_agents_md(repo_root): + rel = os.path.relpath(fpath, repo_root) + with open(fpath, encoding="utf-8", errors="replace") as f: + lines = f.readlines() + for i, line in enumerate(lines, start=1): + if PLACEHOLDER_RE.search(line): + continue + for label, pattern in PATTERNS: + m = pattern.search(line) + if not m: + continue + # Re-check placeholder allowlist against just the matched value, in case + # the placeholder marker sits outside the regex's own match span. + value = m.group(0) + if PLACEHOLDER_RE.search(value): + continue + emit_fail( + f"Possible {label}", + f"{rel}:{i}", + i, + "AGENTS.md is committed content; this line matches a real-looking credential pattern rather than a placeholder.", + "Remove the embedded credential and replace it with an environment variable reference or placeholder (e.g. $API_KEY, ).", + ) + break + +if not findings: + sys.exit(0) + +for desc, fpath, _lineno, why, fix in findings: + print(f"FAIL {desc} — {fpath}") + print(f" Why: {why}") + print(f" Fix: {fix}") + print() + +sys.exit(1) +PYTHON diff --git a/plugins/core/skills/agentsmd-audit/scripts/validate-structure.sh b/plugins/core/skills/agentsmd-audit/scripts/validate-structure.sh new file mode 100755 index 0000000..65c0981 --- /dev/null +++ b/plugins/core/skills/agentsmd-audit/scripts/validate-structure.sh @@ -0,0 +1,118 @@ +#!/usr/bin/env bash +set -euo pipefail + +usage() { + cat < + +Check every AGENTS.md file in a repo (root and nested) for structural +completeness against the agents.md spec's common-sections checklist +(setup/build, code style, testing, security, commit/PR conventions). +Missing individual sections are informational (not every repo needs every +section) — only an empty or entirely unfilled file is a hard failure. + +Arguments: + repo-root Path to the repository root to scan. + +Exit codes: + 0 No FAIL findings (INFO/SUGGESTION may still be printed) + 1 One or more FAIL findings +EOF +} + +if [[ "${1:-}" == "--help" || "${1:-}" == "-h" ]]; then + usage + exit 0 +fi + +if [[ $# -lt 1 ]]; then + echo "Error: repo-root is required." >&2 + echo "" >&2 + usage >&2 + exit 1 +fi + +python3 -u - "$1" <<'PYTHON' +import sys +import os +import re + +PLACEHOLDER_RE = re.compile(r'(?i)FILL IN:|TODO:\s*write|lorem ipsum') + +COMMON_SECTIONS = [ + ("setup/build commands", re.compile(r'(?im)^#{1,3}\s*(setup|install|build|getting started)')), + ("code style", re.compile(r'(?im)^#{1,3}\s*(code style|style guide|conventions)')), + ("testing instructions", re.compile(r'(?im)^#{1,3}\s*(test|testing)')), + ("security considerations", re.compile(r'(?im)^#{1,3}\s*security')), + ("commit/PR conventions", re.compile(r'(?im)^#{1,3}\s*(commit|pr|pull request)')), +] + +repo_root = os.path.abspath(sys.argv[1]) +if not os.path.isdir(repo_root): + print(f"Error: '{repo_root}' is not a directory.", file=sys.stderr) + sys.exit(1) + +EXCLUDE_DIRS = {".git", "node_modules", "vendor", ".venv", "venv", "dist", "build"} + +def find_agents_md(root): + results = [] + for dirpath, dirnames, filenames in os.walk(root): + dirnames[:] = [d for d in dirnames if d not in EXCLUDE_DIRS and not d.startswith(".")] + for fname in filenames: + if fname == "AGENTS.md": + results.append(os.path.join(dirpath, fname)) + return sorted(results) + +has_fail = False +file_contents = {} # rel path -> content, for the duplication pass below + +for fpath in find_agents_md(repo_root): + rel = os.path.relpath(fpath, repo_root) + with open(fpath, encoding="utf-8", errors="replace") as f: + content = f.read() + file_contents[rel] = content + + if not content.strip(): + has_fail = True + print(f"FAIL AGENTS.md is empty — {rel}") + print(" Why: An empty file provides no instructions and gives agents nothing to act on.") + print(" Fix: Add at least a project overview and setup/test commands, per the agents.md common-sections checklist.") + print() + continue + + if PLACEHOLDER_RE.search(content): + has_fail = True + print(f"FAIL Unfilled placeholder content — {rel}") + print(" Why: A 'FILL IN:' or template stub left in place means the file has no repo-specific instructions yet.") + print(" Fix: Replace the placeholder with real, repo-specific content.") + print() + continue + + for label, pattern in COMMON_SECTIONS: + if not pattern.search(content): + print(f"INFO No {label} section — {rel}") + print(f" Note: The agents.md common-sections checklist includes {label}; not every repo needs every section, but confirm this omission is deliberate.") + print() + +# --- Nested-vs-root duplication check --- +root_content = file_contents.get("AGENTS.md") +if root_content: + root_lines = {ln.strip() for ln in root_content.splitlines() if ln.strip()} + for rel, content in file_contents.items(): + if rel == "AGENTS.md": + continue + nested_lines = [ln.strip() for ln in content.splitlines() if ln.strip()] + if not nested_lines: + continue + overlap = sum(1 for ln in nested_lines if ln in root_lines) + ratio = overlap / len(nested_lines) + if ratio >= 0.7: + print(f"SUGGESTION Nested AGENTS.md largely duplicates the root file — {rel}") + print(f" Why: {ratio:.0%} of this file's content lines already appear in the root AGENTS.md; per the spec's nearest-file-wins precedence, nested files don't inherit from the root, but they also shouldn't just restate it.") + print(f" Fix: Trim {rel} down to only what's specific to this package/directory.") + print() + +if has_fail: + sys.exit(1) +sys.exit(0) +PYTHON diff --git a/plugins/core/skills/agentsmd-audit/tests/README.md b/plugins/core/skills/agentsmd-audit/tests/README.md new file mode 100644 index 0000000..ddbfcfd --- /dev/null +++ b/plugins/core/skills/agentsmd-audit/tests/README.md @@ -0,0 +1,30 @@ +# tests/ + +Test files for scripts bundled with this skill. + +## Dependencies + +Tests require [bats-support](https://github.com/bats-core/bats-support) and +[bats-assert](https://github.com/bats-core/bats-assert). The test files load +helpers from the repo root's `tests/test_helper/`. + +From the repo root: + +```bash +git clone https://github.com/bats-core/bats-support tests/test_helper/bats-support +git clone https://github.com/bats-core/bats-assert tests/test_helper/bats-assert +``` + +Run all tests for this skill (from the repo root): + +```bash +bats plugins/core/skills/agentsmd-audit/tests/ +``` + +## Files + +| File | Purpose | +|------|---------| +| `validate-secrets.bats` | Bats test suite for `scripts/validate-secrets.sh` | +| `validate-structure.bats` | Bats test suite for `scripts/validate-structure.sh` | +| `validate-drift.bats` | Bats test suite for `scripts/validate-drift.sh` | diff --git a/plugins/core/skills/agentsmd-audit/tests/validate-drift.bats b/plugins/core/skills/agentsmd-audit/tests/validate-drift.bats new file mode 100644 index 0000000..f76f040 --- /dev/null +++ b/plugins/core/skills/agentsmd-audit/tests/validate-drift.bats @@ -0,0 +1,105 @@ +#!/usr/bin/env bats + +setup() { + REPO_ROOT="$(cd "$BATS_TEST_DIRNAME/../../../../../" && pwd)" + load "$REPO_ROOT/tests/test_helper/bats-support/load" + load "$REPO_ROOT/tests/test_helper/bats-assert/load" + + SCRIPT="$(cd "$BATS_TEST_DIRNAME/../scripts" && pwd)/validate-drift.sh" + TMPDIR="$(mktemp -d)" +} + +teardown() { + rm -rf "$TMPDIR" +} + +@test "fails when AGENTS.md references a stale npm script" { + cat > "$TMPDIR/package.json" <<'EOF' +{ + "scripts": { + "test": "jest" + } +} +EOF + cat > "$TMPDIR/AGENTS.md" <<'EOF' +# AGENTS.md + +## Testing +- Run `pnpm run e2e` before committing. +EOF + run bash "$SCRIPT" "$TMPDIR" + assert_failure + assert_output --partial "e2e" +} + +@test "passes when the referenced npm script exists" { + cat > "$TMPDIR/package.json" <<'EOF' +{ + "scripts": { + "test": "jest" + } +} +EOF + cat > "$TMPDIR/AGENTS.md" <<'EOF' +# AGENTS.md + +## Testing +- Run `npm run test` before committing. +EOF + run bash "$SCRIPT" "$TMPDIR" + assert_success +} + +@test "fails when AGENTS.md references a stale make target" { + cat > "$TMPDIR/Makefile" <<'EOF' +build: + echo building +EOF + cat > "$TMPDIR/AGENTS.md" <<'EOF' +# AGENTS.md + +## Setup +Run `make deploy` to ship. +EOF + run bash "$SCRIPT" "$TMPDIR" + assert_failure + assert_output --partial "deploy" +} + +@test "emits INFO instead of FAIL when there is no package.json to verify an npm script against" { + cat > "$TMPDIR/AGENTS.md" <<'EOF' +# AGENTS.md + +## Testing +Run `pnpm run e2e` before committing. +EOF + run bash "$SCRIPT" "$TMPDIR" + assert_success + assert_output --partial "INFO" + assert_output --partial "e2e" +} + +@test "fails when a referenced file path does not exist" { + cat > "$TMPDIR/AGENTS.md" <<'EOF' +# AGENTS.md + +## Setup +See `scripts/bootstrap.sh` for environment setup. +EOF + run bash "$SCRIPT" "$TMPDIR" + assert_failure + assert_output --partial "scripts/bootstrap.sh" +} + +@test "passes when the referenced file path exists" { + mkdir -p "$TMPDIR/scripts" + : > "$TMPDIR/scripts/bootstrap.sh" + cat > "$TMPDIR/AGENTS.md" <<'EOF' +# AGENTS.md + +## Setup +See `scripts/bootstrap.sh` for environment setup. +EOF + run bash "$SCRIPT" "$TMPDIR" + assert_success +} diff --git a/plugins/core/skills/agentsmd-audit/tests/validate-secrets.bats b/plugins/core/skills/agentsmd-audit/tests/validate-secrets.bats new file mode 100644 index 0000000..0fcbccb --- /dev/null +++ b/plugins/core/skills/agentsmd-audit/tests/validate-secrets.bats @@ -0,0 +1,68 @@ +#!/usr/bin/env bats + +setup() { + REPO_ROOT="$(cd "$BATS_TEST_DIRNAME/../../../../../" && pwd)" + load "$REPO_ROOT/tests/test_helper/bats-support/load" + load "$REPO_ROOT/tests/test_helper/bats-assert/load" + + SCRIPT="$(cd "$BATS_TEST_DIRNAME/../scripts" && pwd)/validate-secrets.sh" + TMPDIR="$(mktemp -d)" +} + +teardown() { + rm -rf "$TMPDIR" +} + +@test "passes on AGENTS.md with no secrets, only placeholders" { + cat > "$TMPDIR/AGENTS.md" <<'EOF' +# AGENTS.md + +## Setup +- Set `export API_KEY=$API_KEY` +- Token: +- DB: postgres://user:changeme@localhost/db +EOF + run bash "$SCRIPT" "$TMPDIR" + assert_success + assert_output "" +} + +@test "fails on a real-looking AWS access key" { + cat > "$TMPDIR/AGENTS.md" <<'EOF' +# AGENTS.md + +## Setup +- AWS_ACCESS_KEY_ID=AKIAABCDEFGHIJKLMNOP # gitleaks:allow (synthetic fixture — this test verifies validate-secrets.sh catches exactly this pattern) +EOF + run bash "$SCRIPT" "$TMPDIR" + assert_failure + assert_output --partial "AWS access key ID" + assert_output --partial "AGENTS.md:4" +} + +@test "fails on a credential-bearing connection string" { + cat > "$TMPDIR/AGENTS.md" <<'EOF' +# AGENTS.md + +## Setup +- DB: postgres://svc_user:h8x2Klm9pQrT@db.internal:5432/prod +EOF + run bash "$SCRIPT" "$TMPDIR" + assert_failure + assert_output --partial "connection string" +} + +@test "detects secrets in a nested AGENTS.md, not just root" { + mkdir -p "$TMPDIR/packages/api" + cat > "$TMPDIR/AGENTS.md" <<'EOF' +# AGENTS.md +Clean root file. +EOF + cat > "$TMPDIR/packages/api/AGENTS.md" <<'EOF' +# API package +- token: ghp_1234567890abcdefghijklmnopqrstuvwxyz01 # gitleaks:allow (synthetic fixture) +EOF + run bash "$SCRIPT" "$TMPDIR" + assert_failure + assert_output --partial "packages/api/AGENTS.md" +} diff --git a/plugins/core/skills/agentsmd-audit/tests/validate-structure.bats b/plugins/core/skills/agentsmd-audit/tests/validate-structure.bats new file mode 100644 index 0000000..aacb39a --- /dev/null +++ b/plugins/core/skills/agentsmd-audit/tests/validate-structure.bats @@ -0,0 +1,76 @@ +#!/usr/bin/env bats + +setup() { + REPO_ROOT="$(cd "$BATS_TEST_DIRNAME/../../../../../" && pwd)" + load "$REPO_ROOT/tests/test_helper/bats-support/load" + load "$REPO_ROOT/tests/test_helper/bats-assert/load" + + SCRIPT="$(cd "$BATS_TEST_DIRNAME/../scripts" && pwd)/validate-structure.sh" + TMPDIR="$(mktemp -d)" +} + +teardown() { + rm -rf "$TMPDIR" +} + +@test "fails on an empty AGENTS.md" { + : > "$TMPDIR/AGENTS.md" + run bash "$SCRIPT" "$TMPDIR" + assert_failure + assert_output --partial "empty" +} + +@test "fails on an unfilled placeholder AGENTS.md" { + cat > "$TMPDIR/AGENTS.md" <<'EOF' +# AGENTS.md + +## Setup +FILL IN: describe setup commands here. +EOF + run bash "$SCRIPT" "$TMPDIR" + assert_failure + assert_output --partial "placeholder" +} + +@test "passes with INFO on real content missing an optional section" { + cat > "$TMPDIR/AGENTS.md" <<'EOF' +# AGENTS.md + +## Setup commands +- Install deps: `pnpm install` +- Run tests: `pnpm test` + +## Code style +- TypeScript strict mode, single quotes, no semicolons. +EOF + run bash "$SCRIPT" "$TMPDIR" + assert_success + assert_output --partial "INFO" + assert_output --partial "security" +} + +@test "suggests trimming a nested AGENTS.md that duplicates the root file" { + mkdir -p "$TMPDIR/packages/api" + cat > "$TMPDIR/AGENTS.md" <<'EOF' +# AGENTS.md + +## Setup commands +- Install deps: `pnpm install` +- Run tests: `pnpm test` +- Lint: `pnpm lint` +- Build: `pnpm build` +EOF + cat > "$TMPDIR/packages/api/AGENTS.md" <<'EOF' +# AGENTS.md + +## Setup commands +- Install deps: `pnpm install` +- Run tests: `pnpm test` +- Lint: `pnpm lint` +- Build: `pnpm build` +EOF + run bash "$SCRIPT" "$TMPDIR" + assert_success + assert_output --partial "SUGGESTION" + assert_output --partial "packages/api/AGENTS.md" +} -- 2.43.0 From 04e7006f768ac0eca63382e7a02017b984f47df3 Mon Sep 17 00:00:00 2001 From: Defame1297 Date: Thu, 23 Jul 2026 17:12:17 +0000 Subject: [PATCH 3/9] fix(core): list scripts/ and tests/ READMEs in agentsmd-audit file table Independent clean-context audit recheck flagged that README.md's file table omitted scripts/README.md and tests/README.md despite both existing on disk, inconsistent with sibling kyberforge skills. --- plugins/core/skills/agentsmd-audit/README.md | 2 ++ plugins/core/skills/agentsmd-audit/SKILL.md | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/plugins/core/skills/agentsmd-audit/README.md b/plugins/core/skills/agentsmd-audit/README.md index 8dfb3e6..105a905 100644 --- a/plugins/core/skills/agentsmd-audit/README.md +++ b/plugins/core/skills/agentsmd-audit/README.md @@ -23,6 +23,8 @@ Provide the path to the repo root to audit when invoking. | `scripts/validate-structure.sh` | Checks for empty/placeholder content, common-sections checklist, nested-vs-root duplication | | `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` | diff --git a/plugins/core/skills/agentsmd-audit/SKILL.md b/plugins/core/skills/agentsmd-audit/SKILL.md index c873582..d8a4a34 100644 --- a/plugins/core/skills/agentsmd-audit/SKILL.md +++ b/plugins/core/skills/agentsmd-audit/SKILL.md @@ -23,7 +23,7 @@ metadata: - context7-websites-agents-md - context7-agentsmd-agents-md - governance-secrets-hard-prohibition - version: "0.1.0" + version: "0.1.1" --- ## Gotchas -- 2.43.0 From 6fd6876264bdd6e89db291745f7036d3e7e2abda Mon Sep 17 00:00:00 2001 From: Defame1297 Date: Thu, 23 Jul 2026 17:19:17 +0000 Subject: [PATCH 4/9] feat(core): add provider-adapter-author skill Converts a target repo's provider-specific instruction file (CLAUDE.md, .cursor/rules, copilot-instructions.md, etc.) into a thin adapter over AGENTS.md, mirroring this repo's own two-tier CLAUDE.md pattern (ADR-0002/0003). Self-validates via a bundled deterministic script (scripts/validate-adapter.sh) rather than a separate paired audit skill. Co-Authored-By: Claude Sonnet 5 --- .../skills/provider-adapter-author/README.md | 30 ++++ .../skills/provider-adapter-author/SKILL.md | 54 +++++++ .../references/sources.md | 9 ++ .../provider-adapter-author/scripts/README.md | 9 ++ .../scripts/validate-adapter.sh | 141 ++++++++++++++++++ .../provider-adapter-author/tests/README.md | 28 ++++ .../tests/validate-adapter.bats | 128 ++++++++++++++++ 7 files changed, 399 insertions(+) create mode 100644 plugins/core/skills/provider-adapter-author/README.md create mode 100644 plugins/core/skills/provider-adapter-author/SKILL.md create mode 100644 plugins/core/skills/provider-adapter-author/references/sources.md create mode 100644 plugins/core/skills/provider-adapter-author/scripts/README.md create mode 100755 plugins/core/skills/provider-adapter-author/scripts/validate-adapter.sh create mode 100644 plugins/core/skills/provider-adapter-author/tests/README.md create mode 100644 plugins/core/skills/provider-adapter-author/tests/validate-adapter.bats diff --git a/plugins/core/skills/provider-adapter-author/README.md b/plugins/core/skills/provider-adapter-author/README.md new file mode 100644 index 0000000..ebd4fe2 --- /dev/null +++ b/plugins/core/skills/provider-adapter-author/README.md @@ -0,0 +1,30 @@ +# provider-adapter-author + +Convert a target repo's provider-specific instruction file (CLAUDE.md, .cursor/rules, copilot-instructions.md, etc.) into a thin adapter over AGENTS.md. + +## What it does + +Detects a provider-specific AI instruction file in a target repo, diffs it against the repo's `AGENTS.md`, and rewrites it down to a minimal reference — an `@AGENTS.md`-style import for providers that support one, or a text pointer for those that don't — plus only genuinely provider-specific additions. Self-validates its own output with a bundled deterministic script (no LLM judgment, no separate audit skill) before finishing. + +## Before you start + +The target repo must already have an `AGENTS.md`. If it doesn't, run `agentsmd-author` first — this skill never creates or edits `AGENTS.md` itself. + +## Usage + +``` +/provider-adapter-author +``` + +Provide the path to the provider-specific file to convert (and the target repo root, if not inferable). Can be invoked directly, or composed into by `agentsmd-author` when it detects an existing provider file with content overlapping AGENTS.md. + +## Files + +| File | Purpose | +|------|---------| +| `SKILL.md` | Skill instructions for agents | +| `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` | diff --git a/plugins/core/skills/provider-adapter-author/SKILL.md b/plugins/core/skills/provider-adapter-author/SKILL.md new file mode 100644 index 0000000..6629822 --- /dev/null +++ b/plugins/core/skills/provider-adapter-author/SKILL.md @@ -0,0 +1,54 @@ +--- +name: provider-adapter-author +description: > + Use when the user wants to convert a provider-specific AI instruction file + (CLAUDE.md, .cursor/rules/*.mdc, copilot-instructions.md, etc.) into a + thin adapter that defers to a repo's AGENTS.md — e.g. "reduce duplication + between CLAUDE.md and AGENTS.md", "make CLAUDE.md just import AGENTS.md" + — even if the pattern isn't named explicitly. Also invoke when + agentsmd-author detects an existing provider file overlapping with + AGENTS.md it just wrote. Detects redundant content in a provider file + relative to AGENTS.md and rewrites it down to a minimal reference (an + `@AGENTS.md`-style import where supported, or a text pointer otherwise) + plus genuinely provider-specific additions. Self-validates via a bundled + deterministic script before finishing. Do not use to write or audit + AGENTS.md itself — use agentsmd-author or agentsmd-audit. +allowed-tools: Bash Read Edit Write +metadata: + category: docs + source_keys: + - adr-0002-0003-two-tier-claude-md + version: "0.1.0" +--- + +## Gotchas + +- Not every provider supports cross-file imports. Claude Code does — a `CLAUDE.md` can consist of nothing but one or more `@path` lines (e.g. `@AGENTS.md`), with no other content required. Cursor's `.cursor/rules/*.mdc` and GitHub Copilot's `copilot-instructions.md` have no native import mechanism as of current tooling — for those, "thin" means a short text pointer to AGENTS.md plus only what that tool actually needs, not a literal import line. Pass `--no-import-syntax` to `scripts/validate-adapter.sh` for these providers. +- This skill never creates or edits `AGENTS.md` itself. If the target repo has no `AGENTS.md` yet, stop and point the user to `agentsmd-author` first — there's nothing to adapt to. +- Only strip content from the provider file that's genuinely redundant with AGENTS.md. Provider-specific material (IDE settings, tool-only syntax, model-specific instructions) stays — the goal is thin, not empty. +- Works standalone or composed-into by `agentsmd-author` — behave identically either way; don't assume a caller skill exists. + +## Step 1 — Detect + +Look for known provider instruction files in the target repo: `CLAUDE.md` (repo root, and any deployed copies), `.cursor/rules/*.mdc`, `.github/copilot-instructions.md`, and similar tool-specific files. Confirm `AGENTS.md` exists at the repo root — if not, stop and tell the user to run `agentsmd-author` first. + +## Step 2 — Diff and rewrite + +Read the provider file and `AGENTS.md` side by side. Separate the provider file's content into two buckets: lines that restate what `AGENTS.md` already owns (universal rules, conventions, project overview) versus lines that are genuinely provider-specific (tool syntax, IDE behavior, model-specific instructions). Rewrite the provider file: + +- **Providers with import syntax** (Claude Code): replace the redundant bucket with an `@AGENTS.md` (or correct relative path) import line, keep the provider-specific bucket below it. +- **Providers without import syntax** (Cursor, Copilot, etc.): replace the redundant bucket with a short pointer sentence mentioning `AGENTS.md`, keep the provider-specific bucket. + +## Step 3 — Self-validate + +Run the bundled check before finishing — this is the skill's own closeout gate; there is no separate paired audit skill for this concern: + +```bash +bash scripts/validate-adapter.sh [--no-import-syntax] [--max-lines N] +``` + +Fix any `FAIL` and re-run until it exits `0`. + +## Step 4 — Report + +State which file was converted, what was removed versus kept, and the validator's final result. diff --git a/plugins/core/skills/provider-adapter-author/references/sources.md b/plugins/core/skills/provider-adapter-author/references/sources.md new file mode 100644 index 0000000..7b7071a --- /dev/null +++ b/plugins/core/skills/provider-adapter-author/references/sources.md @@ -0,0 +1,9 @@ +# Sources + +## adr-0002-0003-two-tier-claude-md + +- **URL:** (in-repo precedent — not an external source or plugin research corpus entry) +- **Description:** This repo's own two-tier CLAUDE.md/AGENTS.md pattern: AGENTS.md is the provider-agnostic source of always-on rules; provider-specific files (CLAUDE.md) become thin adapters that import it (`@AGENTS.md` plus provider-specific additions). Grounds this skill's entire adapter-conversion design — the "thin adapter" shape, the `@`-import convention, and the size/duplication expectations enforced by `scripts/validate-adapter.sh`. +- **Research doc:** docs/adr/0002-two-tier-claude-md.md, docs/adr/0003-agents-md-provider-agnostic-entry-point.md, providers/claude-code/CLAUDE.md (in-repo ADRs and a live example, not a plugin research corpus entry; referenced here since this skill's design is modeled directly on an existing implementation rather than external research) +- **Contributing files:** SKILL.md +- **Status:** `extracted` diff --git a/plugins/core/skills/provider-adapter-author/scripts/README.md b/plugins/core/skills/provider-adapter-author/scripts/README.md new file mode 100644 index 0000000..d137d2b --- /dev/null +++ b/plugins/core/skills/provider-adapter-author/scripts/README.md @@ -0,0 +1,9 @@ +# scripts/ + +Deterministic self-check this skill shells out to instead of relying on LLM judgment for a mechanical check. + +| File | Purpose | +|------|---------| +| `validate-adapter.sh` | Checks a rewritten provider file (CLAUDE.md, etc.) has a reference to AGENTS.md, doesn't duplicate its content, and stays under a thin-file line threshold | + +Takes ` `, with optional `--no-import-syntax` and `--max-lines N` flags. Prints `FAIL` findings to stdout and exits non-zero on any failure. diff --git a/plugins/core/skills/provider-adapter-author/scripts/validate-adapter.sh b/plugins/core/skills/provider-adapter-author/scripts/validate-adapter.sh new file mode 100755 index 0000000..a94d112 --- /dev/null +++ b/plugins/core/skills/provider-adapter-author/scripts/validate-adapter.sh @@ -0,0 +1,141 @@ +#!/usr/bin/env bash +set -euo pipefail + +usage() { + cat < + +Self-check gate for provider-adapter-author. Checks that a rewritten +provider-specific instruction file (CLAUDE.md, .cursor/rules/*.mdc, +copilot-instructions.md, etc.) is actually a thin adapter over AGENTS.md, +not a duplicate copy of it. + +Arguments: + adapter-file Path to the provider-specific file to check. + agents-md-file Path to the AGENTS.md file it should defer to. + +Options: + --no-import-syntax The target provider has no native cross-file import + mechanism. Accept a plain-text pointer mention of + "AGENTS.md" instead of requiring an @import-style line. + --max-lines N Max non-blank lines allowed in the adapter file before + it's considered no longer "thin". Default: 60. + --help, -h Show this help and exit 0. + +Exit codes: + 0 Adapter file passes all checks + 1 One or more checks failed (empty file, no reference to AGENTS.md, + excessive duplication, or file too long) +EOF +} + +NO_IMPORT_SYNTAX=0 +MAX_LINES=60 +ARGS=() + +while [[ $# -gt 0 ]]; do + case "$1" in + --help|-h) + usage + exit 0 + ;; + --no-import-syntax) + NO_IMPORT_SYNTAX=1 + shift + ;; + --max-lines) + MAX_LINES="${2:-}" + shift 2 + ;; + *) + ARGS+=("$1") + shift + ;; + esac +done + +if [[ ${#ARGS[@]} -lt 2 ]]; then + echo "Error: adapter-file and agents-md-file are required." >&2 + echo "" >&2 + usage >&2 + exit 1 +fi + +python3 -u - "${ARGS[0]}" "${ARGS[1]}" "$NO_IMPORT_SYNTAX" "$MAX_LINES" <<'PYTHON' +import sys +import os +import re + +adapter_path, agents_md_path, no_import_syntax, max_lines = sys.argv[1:5] +no_import_syntax = no_import_syntax == "1" +max_lines = int(max_lines) + +if not os.path.isfile(adapter_path): + print(f"Error: '{adapter_path}' is not a file.", file=sys.stderr) + sys.exit(1) +if not os.path.isfile(agents_md_path): + print(f"Error: '{agents_md_path}' is not a file.", file=sys.stderr) + sys.exit(1) + +with open(adapter_path, encoding="utf-8", errors="replace") as f: + adapter_content = f.read() +with open(agents_md_path, encoding="utf-8", errors="replace") as f: + agents_md_content = f.read() + +has_fail = False + +if not adapter_content.strip(): + print(f"FAIL Adapter file is empty — {adapter_path}") + print(" Why: An empty adapter carries no reference to AGENTS.md and no provider-specific content.") + print(" Fix: Add at least an import (or text pointer) to AGENTS.md.") + print() + sys.exit(1) + +IMPORT_RE = re.compile(r'(?m)^\s*@\S*AGENTS\.md\s*$') +lines = adapter_content.splitlines() +import_lines = [ln for ln in lines if IMPORT_RE.match(ln)] + +if no_import_syntax: + has_reference = "AGENTS.md" in adapter_content +else: + has_reference = bool(import_lines) or "AGENTS.md" in adapter_content + +if not has_reference: + has_fail = True + print(f"FAIL Adapter has no reference to AGENTS.md — {adapter_path}") + if no_import_syntax: + print(" Why: This provider has no import syntax, so the adapter must at least mention AGENTS.md as a text pointer.") + print(" Fix: Add a sentence like \"See AGENTS.md at the repo root for shared conventions.\"") + else: + print(" Why: A thin adapter must import AGENTS.md (e.g. `@AGENTS.md`) rather than silently omitting it.") + print(" Fix: Add an `@AGENTS.md` (or equivalent relative path) import line.") + print() + +# --- Duplication check --- +non_import_lines = [ln for ln in lines if not IMPORT_RE.match(ln)] +adapter_lines = [ln.strip() for ln in non_import_lines if ln.strip()] +agents_lines = {ln.strip() for ln in agents_md_content.splitlines() if ln.strip()} + +if adapter_lines: + overlap = sum(1 for ln in adapter_lines if ln in agents_lines) + ratio = overlap / len(adapter_lines) + if ratio > 0.3: + has_fail = True + print(f"FAIL Adapter duplicates AGENTS.md content — {adapter_path}") + print(f" Why: {ratio:.0%} of the adapter's non-import lines already appear verbatim in AGENTS.md. A thin adapter should import shared content, not restate it.") + print(" Fix: Remove the duplicated lines and rely on the AGENTS.md import (or pointer) instead.") + print() + +# --- Size check --- +non_blank_count = len([ln for ln in lines if ln.strip()]) +if non_blank_count > max_lines: + has_fail = True + print(f"FAIL Adapter is not thin — {adapter_path}") + print(f" Why: {non_blank_count} non-blank lines exceeds the {max_lines}-line threshold for a thin adapter.") + print(" Fix: Move provider-agnostic content into AGENTS.md; keep only genuinely provider-specific additions here.") + print() + +if has_fail: + sys.exit(1) +sys.exit(0) +PYTHON diff --git a/plugins/core/skills/provider-adapter-author/tests/README.md b/plugins/core/skills/provider-adapter-author/tests/README.md new file mode 100644 index 0000000..d66b0f8 --- /dev/null +++ b/plugins/core/skills/provider-adapter-author/tests/README.md @@ -0,0 +1,28 @@ +# tests/ + +Test files for scripts bundled with this skill. + +## Dependencies + +Tests require [bats-support](https://github.com/bats-core/bats-support) and +[bats-assert](https://github.com/bats-core/bats-assert). The test files load +helpers from the repo root's `tests/test_helper/`. + +From the repo root: + +```bash +git clone https://github.com/bats-core/bats-support tests/test_helper/bats-support +git clone https://github.com/bats-core/bats-assert tests/test_helper/bats-assert +``` + +Run all tests for this skill (from the repo root): + +```bash +bats plugins/core/skills/provider-adapter-author/tests/ +``` + +## Files + +| File | Purpose | +|------|---------| +| `validate-adapter.bats` | Bats test suite for `scripts/validate-adapter.sh` | diff --git a/plugins/core/skills/provider-adapter-author/tests/validate-adapter.bats b/plugins/core/skills/provider-adapter-author/tests/validate-adapter.bats new file mode 100644 index 0000000..052d0d9 --- /dev/null +++ b/plugins/core/skills/provider-adapter-author/tests/validate-adapter.bats @@ -0,0 +1,128 @@ +#!/usr/bin/env bats + +setup() { + REPO_ROOT="$(cd "$BATS_TEST_DIRNAME/../../../../../" && pwd)" + load "$REPO_ROOT/tests/test_helper/bats-support/load" + load "$REPO_ROOT/tests/test_helper/bats-assert/load" + + SCRIPT="$(cd "$BATS_TEST_DIRNAME/../scripts" && pwd)/validate-adapter.sh" + TMPDIR="$(mktemp -d)" + AGENTS_MD="$TMPDIR/AGENTS.md" + cat > "$AGENTS_MD" <<'EOF' +# AGENTS.md + +## Setup commands +- Install deps: `pnpm install` +- Run tests: `pnpm test` + +## Code style +- TypeScript strict mode, single quotes, no semicolons. +EOF +} + +teardown() { + rm -rf "$TMPDIR" +} + +@test "fails when the adapter file is empty" { + ADAPTER="$TMPDIR/CLAUDE.md" + : > "$ADAPTER" + run bash "$SCRIPT" "$ADAPTER" "$AGENTS_MD" + assert_failure + assert_output --partial "empty" +} + +@test "fails when the adapter has no reference to AGENTS.md" { + ADAPTER="$TMPDIR/CLAUDE.md" + cat > "$ADAPTER" <<'EOF' +# Claude-specific notes +Use the internal linter before committing. +EOF + run bash "$SCRIPT" "$ADAPTER" "$AGENTS_MD" + assert_failure + assert_output --partial "no reference" +} + +@test "passes a thin adapter with an @import line and provider-specific additions" { + ADAPTER="$TMPDIR/CLAUDE.md" + cat > "$ADAPTER" <<'EOF' +@AGENTS.md +@core/instructions/governance.md +EOF + run bash "$SCRIPT" "$ADAPTER" "$AGENTS_MD" + assert_success +} + +@test "fails when the adapter duplicates most of AGENTS.md's content" { + ADAPTER="$TMPDIR/CLAUDE.md" + cat > "$ADAPTER" <<'EOF' +@AGENTS.md + +## Setup commands +- Install deps: `pnpm install` +- Run tests: `pnpm test` + +## Code style +- TypeScript strict mode, single quotes, no semicolons. +EOF + run bash "$SCRIPT" "$ADAPTER" "$AGENTS_MD" + assert_failure + assert_output --partial "duplicat" +} + +@test "fails when the adapter exceeds the max line threshold" { + ADAPTER="$TMPDIR/CLAUDE.md" + { + echo "@AGENTS.md" + for i in $(seq 1 80); do echo "Provider-specific line $i unrelated to AGENTS.md content."; done + } > "$ADAPTER" + run bash "$SCRIPT" "$ADAPTER" "$AGENTS_MD" + assert_failure + assert_output --partial "thin" +} + +@test "allows a custom --max-lines threshold" { + ADAPTER="$TMPDIR/CLAUDE.md" + { + echo "@AGENTS.md" + for i in $(seq 1 10); do echo "Provider-specific line $i unrelated to AGENTS.md content."; done + } > "$ADAPTER" + run bash "$SCRIPT" --max-lines 5 "$ADAPTER" "$AGENTS_MD" + assert_failure + assert_output --partial "thin" +} + +@test "with --no-import-syntax, a text pointer to AGENTS.md is accepted instead of an @import line" { + ADAPTER="$TMPDIR/copilot-instructions.md" + cat > "$ADAPTER" <<'EOF' +See AGENTS.md at the repo root for setup, style, and testing conventions. + +## Copilot-specific +Prefer inline suggestions over chat for one-line edits. +EOF + run bash "$SCRIPT" --no-import-syntax "$ADAPTER" "$AGENTS_MD" + assert_success +} + +@test "with --no-import-syntax, still fails if there is no mention of AGENTS.md at all" { + ADAPTER="$TMPDIR/copilot-instructions.md" + cat > "$ADAPTER" <<'EOF' +## Copilot-specific +Prefer inline suggestions over chat for one-line edits. +EOF + run bash "$SCRIPT" --no-import-syntax "$ADAPTER" "$AGENTS_MD" + assert_failure + assert_output --partial "no reference" +} + +@test "--help exits 0 and documents usage" { + run bash "$SCRIPT" --help + assert_success + assert_output --partial "Usage:" +} + +@test "fails with a clear error when the adapter file argument is missing" { + run bash "$SCRIPT" + assert_failure + assert_output --partial "required" +} -- 2.43.0 From 956ff7a54a2caccec719d6ddf27477a56839fa8c Mon Sep 17 00:00:00 2001 From: Defame1297 Date: Thu, 23 Jul 2026 17:25:43 +0000 Subject: [PATCH 5/9] feat(core): add agentsmd-author skill Creates/updates a target repo's AGENTS.md by exploring real repo conventions, supports nested monorepo placement, closes out via agentsmd-audit, and composes into provider-adapter-author for provider-file reconciliation. Completes the three-skill trio from ADR-0012. --- plugins/core/skills/agentsmd-author/README.md | 26 +++++++++ plugins/core/skills/agentsmd-author/SKILL.md | 56 +++++++++++++++++++ .../agentsmd-author/references/sources.md | 25 +++++++++ 3 files changed, 107 insertions(+) create mode 100644 plugins/core/skills/agentsmd-author/README.md create mode 100644 plugins/core/skills/agentsmd-author/SKILL.md create mode 100644 plugins/core/skills/agentsmd-author/references/sources.md diff --git a/plugins/core/skills/agentsmd-author/README.md b/plugins/core/skills/agentsmd-author/README.md new file mode 100644 index 0000000..fb5915e --- /dev/null +++ b/plugins/core/skills/agentsmd-author/README.md @@ -0,0 +1,26 @@ +# agentsmd-author + +Create or update a target repo's AGENTS.md file(s) by exploring the repo for real conventions. + +## What it does + +Explores a target repo (package manager scripts, Makefile/task runner, CI config, linter config, existing docs) and writes or updates `AGENTS.md` with only verified commands and conventions — never invented ones. Supports nested monorepo placement, following the agents.md standard's nearest-file-wins precedence. Closes every run by invoking `agentsmd-audit` inline, and hands off to `provider-adapter-author` when an existing provider-specific file (CLAUDE.md, etc.) now duplicates content AGENTS.md owns. + +## Before you start + +The `agentsmd-audit` skill must be available (co-installed in the `core` plugin) — this skill invokes it as a mandatory closeout step. + +## Usage + +``` +/agentsmd-author +``` + +Provide the target repo root (defaults to the current directory) and, if relevant, which subdirectory should get a nested AGENTS.md. + +## Files + +| File | Purpose | +|------|---------| +| `SKILL.md` | Skill instructions for agents | +| `references/sources.md` | Provenance record — sources that informed this skill and which files each contributed to | diff --git a/plugins/core/skills/agentsmd-author/SKILL.md b/plugins/core/skills/agentsmd-author/SKILL.md new file mode 100644 index 0000000..895699a --- /dev/null +++ b/plugins/core/skills/agentsmd-author/SKILL.md @@ -0,0 +1,56 @@ +--- +name: agentsmd-author +description: > + Use when the user wants to create or update a repo's AGENTS.md file + ("write an AGENTS.md for this repo", "add setup/test instructions for + agents", "update AGENTS.md", "give this package its own AGENTS.md") — even + if they don't name the file explicitly, e.g. "document this for AI coding + tools" or "make sure agents know how to run tests here". Writes/updates + AGENTS.md by exploring the target repo for real build, test, lint, and + style conventions — never invents commands. Supports nested monorepo + placement (a subdirectory can get its own AGENTS.md following + nearest-file-wins precedence). Closes every run by invoking agentsmd-audit + inline, and calls provider-adapter-author when an existing provider file + (CLAUDE.md, etc.) now duplicates what AGENTS.md owns. Do not use to review + an existing AGENTS.md without changing it — use agentsmd-audit instead. Do + not use to convert CLAUDE.md/.cursor/rules into a thin adapter — use + provider-adapter-author instead. +allowed-tools: Bash Read Write Edit +metadata: + category: docs + source_keys: + - agents-md-official + - context7-websites-agents-md + - context7-agentsmd-agents-md + version: "0.1.0" +--- + +## Gotchas + +- Never invent a command. Every line under a setup/test/build section must come from something you actually found in the repo (`package.json` scripts, a `Makefile` target, a CI workflow step, a README). If you can't verify a command, don't include it. +- AGENTS.md has no required schema — don't force every common-sections-checklist heading into every repo. Include only sections that reflect something real about this repo; a thin, accurate file beats a padded, generic one. +- Nested placement is for genuinely different conventions, not convenience. Only create a subdirectory AGENTS.md when that subtree has its own build tool, stack, or conventions distinct from the root — otherwise you're duplicating content the root already covers, which the nearest-file-wins rule doesn't merge back together. +- This skill never touches CLAUDE.md, `.cursor/rules/*.mdc`, `copilot-instructions.md`, or similar provider files directly — that's `provider-adapter-author`'s job. Detect and hand off; don't reconcile it yourself. +- This skill never audits on its own judgment — the closing `agentsmd-audit` invocation is mandatory, not optional, even when the change looks trivial. + +## Step 1 — Explore the target repo + +Before writing anything, gather real facts: package manager and scripts (`package.json`, `pyproject.toml`, `Cargo.toml`, etc.), a `Makefile` or task runner, CI config (`.github/workflows/`, etc.) for the commands it actually runs, linter/formatter config files, and any existing docs (`README.md`, existing `AGENTS.md`) describing conventions. Note whether any subdirectory looks like its own package with a different stack. + +## Step 2 — Decide placement + +- No `AGENTS.md` at the repo root yet → create one there first, covering whole-repo conventions. +- A subdirectory has materially different build/test tooling or conventions than the root → create or update a nested `AGENTS.md` there, scoped to what's different. Don't repeat root-level content — the nearest-file-wins rule means the nested file is read alone, not merged with the root. +- Otherwise → update the existing file(s) in place. + +## Step 3 — Write or update + +Use only sections that reflect something real about the repo. Common sections from the agents.md standard — setup/build commands, code style, testing instructions, security considerations, commit/PR conventions — are a checklist to consider, not a template to fill blindly. Prefer concrete commands and file paths over general advice. + +## Step 4 — Check for an existing provider file + +Look for `CLAUDE.md`, `.cursor/rules/*.mdc`, `.github/copilot-instructions.md`, or similar in the target repo. If one exists and now duplicates content the AGENTS.md you just wrote/updated already owns, invoke the `provider-adapter-author` skill on it to reconcile — don't rewrite it yourself. + +## Step 5 — Audit and report + +Invoke the `agentsmd-audit` skill directly on the AGENTS.md file(s) you just wrote or updated. Resolve any FAIL findings before considering the work done — re-invoke this skill's own writing steps to fix them, then re-run the audit, same as any other close-the-loop check. Report what was created/changed, whether a provider file was reconciled, and the audit's final result. diff --git a/plugins/core/skills/agentsmd-author/references/sources.md b/plugins/core/skills/agentsmd-author/references/sources.md new file mode 100644 index 0000000..68849f0 --- /dev/null +++ b/plugins/core/skills/agentsmd-author/references/sources.md @@ -0,0 +1,25 @@ +# Sources + +## agents-md-official + +- **URL:** https://agents.md/ +- **Description:** Official agents.md website — format spec, common-sections checklist, precedence rules (nearest-file-wins, no merge across files), monorepo nesting patterns +- **Research doc:** plugins/core/docs/research/docs/agentsmd/sources.md +- **Contributing files:** SKILL.md +- **Status:** `extracted` + +## context7-websites-agents-md + +- **URL:** context7:/websites/agents_md +- **Description:** Context7 index of the official agents.md website — overview, governance, cross-tool compatibility, configuration examples +- **Research doc:** plugins/core/docs/research/docs/agentsmd/sources.md +- **Contributing files:** SKILL.md +- **Status:** `extracted` + +## context7-agentsmd-agents-md + +- **URL:** context7:/agentsmd/agents.md +- **Description:** Context7 index of the agentsmd/agents.md repository — format spec, nested monorepo patterns, file structure examples +- **Research doc:** plugins/core/docs/research/docs/agentsmd/sources.md +- **Contributing files:** SKILL.md +- **Status:** `extracted` -- 2.43.0 From d6b0292da7bd688e2a3dc97bab01ad78f45ede49 Mon Sep 17 00:00:00 2001 From: Defame1297 Date: Thu, 23 Jul 2026 17:29:02 +0000 Subject: [PATCH 6/9] chore(core): bump version to 1.1.0 for new skill content core gained three skills for the first time (agentsmd-author, agentsmd-audit, provider-adapter-author). Minor bump reflects new capability rather than a fix. Also declares the missing `skills` path in the Copilot manifest so Copilot CLI discovers them (CC auto-discovers from the plugin root; Copilot requires explicit declaration per ADR-0016 convention). Co-Authored-By: Claude Sonnet 5 --- plugins/core/.claude-plugin/plugin.json | 2 +- plugins/core/plugin.json | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/plugins/core/.claude-plugin/plugin.json b/plugins/core/.claude-plugin/plugin.json index 76229b3..2fc0c23 100644 --- a/plugins/core/.claude-plugin/plugin.json +++ b/plugins/core/.claude-plugin/plugin.json @@ -14,5 +14,5 @@ ], "license": "MIT", "name": "core", - "version": "1.0.0" + "version": "1.1.0" } diff --git a/plugins/core/plugin.json b/plugins/core/plugin.json index e0d2f31..c24ed8e 100644 --- a/plugins/core/plugin.json +++ b/plugins/core/plugin.json @@ -15,5 +15,8 @@ "license": "MIT", "mcpServers": ".mcp.json", "name": "core", - "version": "1.0.0" + "skills": [ + "skills/" + ], + "version": "1.1.0" } -- 2.43.0 From 1fcee54c1e6dd06c153eb95efa07d87690ceb09a Mon Sep 17 00:00:00 2001 From: Defame1297 Date: Thu, 23 Jul 2026 17:31:04 +0000 Subject: [PATCH 7/9] docs(context): fix stale ADR-0012 references to correct ADR-0002/0003 --- CONTEXT.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CONTEXT.md b/CONTEXT.md index af6efa6..138fa75 100644 --- a/CONTEXT.md +++ b/CONTEXT.md @@ -8,7 +8,7 @@ description: Domain language and decisions for the global AI development config ## Principles ### CLAUDE.md index model -`AGENTS.md` is the source of always-on universal rules (provider-agnostic). `providers/claude-code/CLAUDE.md` is a thin adapter: it imports `~/.agents/AGENTS.md` via `@~/.agents/AGENTS.md` and appends Claude Code-specific additions (`@import` for governance.md, content index). Deployed to `~/.claude/CLAUDE.md` via `install.sh`. Context size is kept minimal — only what is needed every session is loaded upfront; detailed content is pulled on demand. See ADR-0012. +`AGENTS.md` is the source of always-on universal rules (provider-agnostic). `providers/claude-code/CLAUDE.md` is a thin adapter: it imports `~/.agents/AGENTS.md` via `@~/.agents/AGENTS.md` and appends Claude Code-specific additions (`@import` for governance.md, content index). Deployed to `~/.claude/CLAUDE.md` via `install.sh`. Context size is kept minimal — only what is needed every session is loaded upfront; detailed content is pulled on demand. See ADR-0003. ### Instruction file format `core/instructions/.md` files are plain markdown — no frontmatter, no schema. The agent decides when to read each file based on task context and the content index label in `providers/claude-code/CLAUDE.md`. Frontmatter is deferred until there is evidence that agents are loading the wrong files in practice. @@ -46,7 +46,7 @@ The provider-agnostic always-on instruction entry point. Two files: - **Repo-level `AGENTS.md`** — instructions for agents working inside this repo (structure, key rules); imported by repo `CLAUDE.md` via `@AGENTS.md`. - **Global `core/AGENTS.md`** — Communication and Behavior rules that apply across all projects; deployed to `~/.agents/AGENTS.md`; imported by `~/.claude/CLAUDE.md` via `@~/.agents/AGENTS.md`. -Contains always-on rules in plain markdown with no provider-specific syntax (no `@import`). Provider-specific files (`CLAUDE.md`) are thin adapters that import the relevant `AGENTS.md` and add only Claude Code-specific syntax. This pattern means a single source of truth can serve multiple providers without duplication. See ADR-0012. +Contains always-on rules in plain markdown with no provider-specific syntax (no `@import`). Provider-specific files (`CLAUDE.md`) are thin adapters that import the relevant `AGENTS.md` and add only Claude Code-specific syntax. This pattern means a single source of truth can serve multiple providers without duplication. See ADR-0003. ### Skill composition A skill calling another skill by name to delegate a sub-task. The calling skill focuses on the orchestration decision ("when to do X"); the called skill owns the mechanics ("how to do X"). Established compositions: `grill-me` calls `write-adr` when a decision crystallises; `implement-feature` calls `tdd` as its implementation methodology; `forge` calls `grill-with-docs` to refine intent, classifies the target artifact type (skill / agent / plugin / marketplace entry), then routes to the matching `*-author` skill — which owns its own create/improve logic and, where applicable, its own inline audit closeout (`skill-author` runs `/skill-audit`, `agent-author` runs `kyberforge:agent-audit`, both in the same context as the authoring work). `forge` additionally runs its own independent recheck after a skill/agent route finishes: a clean-context subagent (not forked, no inherited context) re-runs the same audit skill against the finished artifact, as a distinct verification layer from the author skill's inline audit — the two can share blind spots since the inline audit runs in the same context as the work it checks. If the clean audit surfaces any unresolved finding, `forge` loops — re-invoke the author skill to resolve it, re-run the clean audit — until the clean audit comes back with nothing unresolved; only then is the route done. `plugin-author` and `marketplace-author` have no audit counterpart and get no recheck; their terminal check is `claude plugin validate`. @@ -64,7 +64,7 @@ Files that reference other files should declare those references explicitly. The A skill pair in the `core` plugin for writing, updating, and reviewing a target repo's `AGENTS.md` file(s) (the generic open-standard file — see the `AGENTS.md` entry above — not this repo's own). `agentsmd-author` creates/updates AGENTS.md content, supports nested monorepo placement (per the standard's nearest-file-wins precedence), and closes out by invoking `agentsmd-audit` inline. `agentsmd-audit` runs a single combined pass checking three mandatory baselines: secrets/credentials (governance.md hard prohibition — AGENTS.md is committed content), structural completeness (common-sections checklist from the agents.md spec), and accuracy/drift (do referenced commands and paths actually resolve against the repo). `agentsmd-audit` never inspects provider adapter files (see `provider-adapter-author`) — its scope is AGENTS.md content only. Chosen over folding this into `kyberforge` because kyberforge's scope is meta-tooling for the holocron marketplace itself, not generic target-repo documentation; `core` is the intended home for cross-cutting, repo-agnostic utility skills. ### provider-adapter-author -A companion skill (`core` plugin) that detects a target repo's provider-specific instruction file (`CLAUDE.md`, `.cursor/rules/*.mdc`, `copilot-instructions.md`, etc.) and, where it duplicates content AGENTS.md should own, converts it into a thin adapter that imports AGENTS.md — mirroring this repo's own ADR-0012 pattern. Self-validates via its own bundled deterministic script (`scripts/validate-adapter.sh`: checks for an import reference, no duplicated headings, size threshold) rather than a separate paired audit skill — the check is mechanical, so a script suffices per governance.md's "prefer deterministic code for repeatable tasks." `agentsmd-author` calls this skill via skill composition when it detects an existing provider file with overlapping content. +A companion skill (`core` plugin) that detects a target repo's provider-specific instruction file (`CLAUDE.md`, `.cursor/rules/*.mdc`, `copilot-instructions.md`, etc.) and, where it duplicates content AGENTS.md should own, converts it into a thin adapter that imports AGENTS.md — mirroring this repo's own ADR-0002/ADR-0003 two-tier adapter pattern. Self-validates via its own bundled deterministic script (`scripts/validate-adapter.sh`: checks for an import reference, no duplicated headings, size threshold) rather than a separate paired audit skill — the check is mechanical, so a script suffices per governance.md's "prefer deterministic code for repeatable tasks." `agentsmd-author` calls this skill via skill composition when it detects an existing provider file with overlapping content. ### LESSONS.md Long-loop feedback log for patterns observed across sessions. Three or more entries on the same pattern graduate to the relevant standing file (e.g. a coding convention, a governance rule). Updated by the session-handoff skill or directly by the human. Lives at the repo root. -- 2.43.0 From 250c486ce17dcf87d8f45c38ea1ae537e3b0e8b2 Mon Sep 17 00:00:00 2001 From: Defame1297 Date: Thu, 23 Jul 2026 17:31:14 +0000 Subject: [PATCH 8/9] docs(core): add plugin README --- plugins/core/README.md | 47 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 plugins/core/README.md diff --git a/plugins/core/README.md b/plugins/core/README.md new file mode 100644 index 0000000..ec8bc67 --- /dev/null +++ b/plugins/core/README.md @@ -0,0 +1,47 @@ +# core + +Cross-cutting utility skills for everyday AI-assisted coding — triage, diagnosis, architecture review, and session navigation. + +## Install + +**Claude Code:** + +```bash +claude plugin marketplace add / +claude plugin install core@ +``` + +**GitHub Copilot CLI:** + +```bash +copilot plugin marketplace add / +copilot plugin install core +``` + +**Local (development):** + +```bash +# Claude Code +claude --plugin-dir ./plugins/core + +# GitHub Copilot CLI +copilot plugin install ./plugins/core +``` + +## Contents + +| Component | Path | Description | +|---|---|---| +| Skills | `skills/` | Slash commands available after install | + +## Skills + +| Skill | Description | +|---|---| +| `agentsmd-author` | Create or update a repo's AGENTS.md by exploring real build/test/lint conventions; supports nested monorepo placement and hands off to agentsmd-audit and provider-adapter-author | +| `agentsmd-audit` | Audit a repo's AGENTS.md for embedded secrets, structural completeness, and drift; produces a findings report | +| `provider-adapter-author` | Convert a provider-specific instruction file (CLAUDE.md, `.cursor/rules/*.mdc`, copilot-instructions.md, etc.) into a thin adapter that defers to AGENTS.md | + +## Author + +Defame1297 -- 2.43.0 From bb34aa0eb5bc3790abc35d19a86f1b16495b5037 Mon Sep 17 00:00:00 2001 From: Defame1297 Date: Thu, 23 Jul 2026 17:40:27 +0000 Subject: [PATCH 9/9] feat(core): add content-guide.md to agentsmd-author PR review feedback: Step 3 gave no concrete guidance on what good AGENTS.md content looks like, and the skill had no substantive references file (only provenance bookkeeping in sources.md), unlike sibling kyberforge skills. Adds section-by-section content guidance, the worked example, and monorepo precedence rules synthesized from the agentsmd research corpus. Co-Authored-By: Claude Sonnet 5 --- plugins/core/skills/agentsmd-author/README.md | 1 + plugins/core/skills/agentsmd-author/SKILL.md | 4 +- .../references/content-guide.md | 118 ++++++++++++++++++ .../agentsmd-author/references/sources.md | 6 +- 4 files changed, 124 insertions(+), 5 deletions(-) create mode 100644 plugins/core/skills/agentsmd-author/references/content-guide.md diff --git a/plugins/core/skills/agentsmd-author/README.md b/plugins/core/skills/agentsmd-author/README.md index fb5915e..e7ec1d5 100644 --- a/plugins/core/skills/agentsmd-author/README.md +++ b/plugins/core/skills/agentsmd-author/README.md @@ -23,4 +23,5 @@ Provide the target repo root (defaults to the current directory) and, if relevan | File | Purpose | |------|---------| | `SKILL.md` | Skill instructions for agents | +| `references/content-guide.md` | Section-by-section AGENTS.md content guidance, a worked example, and monorepo/nested-file precedence rules | | `references/sources.md` | Provenance record — sources that informed this skill and which files each contributed to | diff --git a/plugins/core/skills/agentsmd-author/SKILL.md b/plugins/core/skills/agentsmd-author/SKILL.md index 895699a..a38604d 100644 --- a/plugins/core/skills/agentsmd-author/SKILL.md +++ b/plugins/core/skills/agentsmd-author/SKILL.md @@ -22,7 +22,7 @@ metadata: - agents-md-official - context7-websites-agents-md - context7-agentsmd-agents-md - version: "0.1.0" + version: "0.1.1" --- ## Gotchas @@ -45,7 +45,7 @@ Before writing anything, gather real facts: package manager and scripts (`packag ## Step 3 — Write or update -Use only sections that reflect something real about the repo. Common sections from the agents.md standard — setup/build commands, code style, testing instructions, security considerations, commit/PR conventions — are a checklist to consider, not a template to fill blindly. Prefer concrete commands and file paths over general advice. +Use only sections that reflect something real about the repo — never fill in every common-sections-checklist heading just because it exists. Read `references/content-guide.md` for section-by-section guidance, a worked example, and what separates useful content from generic padding, before writing. ## Step 4 — Check for an existing provider file diff --git a/plugins/core/skills/agentsmd-author/references/content-guide.md b/plugins/core/skills/agentsmd-author/references/content-guide.md new file mode 100644 index 0000000..19ebad1 --- /dev/null +++ b/plugins/core/skills/agentsmd-author/references/content-guide.md @@ -0,0 +1,118 @@ +--- +source_keys: + - agents-md-official + - context7-websites-agents-md + - context7-agentsmd-agents-md +--- + +# What good AGENTS.md content looks like + +AGENTS.md has no required schema — there's no field to fill in, only sections that either +earn their place or don't. Agents treat this file as a set of live directives, not +documentation: they will actually run the commands it lists and fix failures before +finishing a task. That means a wrong or stale line is worse than a missing one. Verify +every command against something real in the repo before writing it down. + +## Section-by-section guidance + +**Setup / build commands** — the install and dev-server commands, exactly as they appear +in `package.json` scripts, a `Makefile`, or a `Cargo.toml`/`pyproject.toml` equivalent. One +line per command, each with a one-clause note on what it does if the name alone isn't +obvious. Skip this section if there's genuinely nothing beyond "clone and run" — don't pad +it with a restated `git clone`. + +**Code style** — only conventions that aren't already enforced by a linter/formatter config +the agent will pick up on its own (a `.eslintrc`, `rustfmt.toml`, etc. speaks for itself). +Write down the conventions that live only in people's heads: naming patterns, module +boundaries, patterns to avoid, anything a linter can't catch. If the repo has no +undocumented conventions beyond what tooling enforces, skip this section. + +**Testing instructions** — the exact command(s) to run the suite, where to find +per-package or per-workflow test configuration (e.g. `.github/workflows/`), and any +non-obvious requirement (a service that must be running, an env var that must be set). +State plainly that the agent should run tests before considering a change done and fix +failures — don't leave this implicit. + +**Security considerations** — only repo-specific hazards: a data-handling boundary, a +credential pattern to never hardcode, a destructive command that needs a confirmation +step. Do not restate general security advice ("don't commit secrets") that any agent +already assumes — that's padding, not a directive. + +**Commit / PR conventions** — the title/format convention if one exists (e.g. a +Conventional Commits type prefix, a ticket-number requirement), and any check that must +pass before a PR is opened (lint, test, type-check). Point at the real command, not +"make sure it passes." + +**Dev environment tips** — the handful of things that save real time and are easy to miss: +how to jump to a specific package in a monorepo without `ls`-ing around, how to register a +new package so the toolchain sees it, where to look up a canonical name/id. This section +is for genuine friction points observed in this repo, not generic advice. + +## What separates useful content from padding + +A useful section names a real file, command, or path that exists in this repo right now. +A padded section could be pasted into any repo unchanged and still "make sense" — that's +the tell. If a sentence would read the same in a different codebase, it doesn't belong. +Prefer four accurate lines over twelve generic ones. + +## Worked example (minimal project) + +```markdown +# AGENTS.md + +## Setup commands +- Install deps: `pnpm install` +- Start dev server: `pnpm dev` +- Run tests: `pnpm test` + +## Code style +- TypeScript strict mode +- Single quotes, no semicolons +- Use functional patterns where possible + +## Dev environment tips +- Use `pnpm dlx turbo run where ` to jump to a package instead of scanning with `ls`. +- Run `pnpm install --filter ` to add the package to your workspace so Vite, ESLint, and TypeScript can see it. +- Check the `name` field inside each package's `package.json` to confirm the right name. + +## Testing instructions +- Find the CI plan in the `.github/workflows` folder. +- Run `pnpm turbo run test --filter ` to run every check defined for that package. +- From the package root you can just call `pnpm test`. The commit should pass all tests before you merge. +- Fix any test or type errors until the whole suite is green. +- Add or update tests for the code you change, even if nobody asked. + +## PR instructions +- Title format: [] +- Always run `pnpm lint` and `pnpm test` before committing. +``` + +Every line above names a real command or path — that's the standard to hold this repo's +version to, not the specific tooling shown (a Python/Cargo/Go repo's AGENTS.md should look +nothing like this one in its specifics, only in how concrete each line is). + +## Monorepo / nested placement + +``` +my-monorepo/ +├── AGENTS.md # Root-level: applies to the whole repo +├── packages/ +│ ├── api/ +│ │ └── AGENTS.md # API-specific instructions; overrides root for this package +│ ├── web/ +│ │ └── AGENTS.md # Web app-specific instructions +│ └── shared/ +│ └── AGENTS.md # Shared library instructions +``` + +Precedence rule: the file nearest the edited path wins. Nested files are **not** merged +with the root file — an agent editing inside `packages/api/` reads only +`packages/api/AGENTS.md`, never the root file in addition. Consequences: + +- A nested file must stand alone. Don't write "also see the root file" — write what the + agent needs, full stop. +- Don't duplicate root content in a nested file "just in case." If a nested file repeats + root-level setup instructions verbatim, that's a sign it shouldn't exist as a separate + file at all — the subtree isn't actually different enough to warrant one. +- Only create a nested file when the subtree has a genuinely different stack, build tool, + or convention than the root (see `SKILL.md` Step 2 for the placement decision itself). diff --git a/plugins/core/skills/agentsmd-author/references/sources.md b/plugins/core/skills/agentsmd-author/references/sources.md index 68849f0..5fec8fc 100644 --- a/plugins/core/skills/agentsmd-author/references/sources.md +++ b/plugins/core/skills/agentsmd-author/references/sources.md @@ -5,7 +5,7 @@ - **URL:** https://agents.md/ - **Description:** Official agents.md website — format spec, common-sections checklist, precedence rules (nearest-file-wins, no merge across files), monorepo nesting patterns - **Research doc:** plugins/core/docs/research/docs/agentsmd/sources.md -- **Contributing files:** SKILL.md +- **Contributing files:** SKILL.md, references/content-guide.md - **Status:** `extracted` ## context7-websites-agents-md @@ -13,7 +13,7 @@ - **URL:** context7:/websites/agents_md - **Description:** Context7 index of the official agents.md website — overview, governance, cross-tool compatibility, configuration examples - **Research doc:** plugins/core/docs/research/docs/agentsmd/sources.md -- **Contributing files:** SKILL.md +- **Contributing files:** SKILL.md, references/content-guide.md - **Status:** `extracted` ## context7-agentsmd-agents-md @@ -21,5 +21,5 @@ - **URL:** context7:/agentsmd/agents.md - **Description:** Context7 index of the agentsmd/agents.md repository — format spec, nested monorepo patterns, file structure examples - **Research doc:** plugins/core/docs/research/docs/agentsmd/sources.md -- **Contributing files:** SKILL.md +- **Contributing files:** SKILL.md, references/content-guide.md - **Status:** `extracted` -- 2.43.0