fix(kyberforge): address agent-audit audit findings in validate-provenance.sh

## Why

Two issues were found in `validate-provenance.sh` by `/skill-audit`:

1. `find_plugin_root` only walked up looking for bare `plugin.json`, missing
   the `.claude-plugin/plugin.json` layout used by kyberforge plugins — matching
   the logic already present in `validate.sh`.

2. Check numbers in `--help` and inline comments had a gap (0,1,2,4,5,6) from
   a previously removed check, making the numbering confusing to readers.

## Implementation Notes

Check numbers renumbered sequentially 0–5 in both the `--help` output block
and the inline `# --- Check N:` comments. The `find_plugin_root` condition now
mirrors the `detect_scope` function in `validate.sh`.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0147vXtL5sP6vorDdqXGJJU9
This commit is contained in:
2026-07-04 11:33:03 +00:00
parent fe34daeed7
commit e58234eaf9

View File

@@ -19,9 +19,9 @@ Checks performed:
0 source_keys present in agent pair but agents/sources.md absent
1 FILL IN: placeholders in agents/sources.md
2 source_keys in agent files → slug exists in agents/sources.md
4 Contributing files listed in agents/sources.md exist on disk (plugin-root relative)
5 Contributing files back-reference the parent slug in their source_keys
6 Research doc field present and not placeholder
3 Contributing files listed in agents/sources.md exist on disk (plugin-root relative)
4 Contributing files back-reference the parent slug in their source_keys
5 Research doc field present and not placeholder
EOF
}
@@ -61,7 +61,7 @@ else:
def find_plugin_root(start_dir):
current = os.path.abspath(start_dir)
while True:
if os.path.isfile(os.path.join(current, 'plugin.json')):
if (os.path.isfile(os.path.join(current, 'plugin.json')) or os.path.isfile(os.path.join(current, '.claude-plugin', 'plugin.json'))):
return current
parent = os.path.dirname(current)
if parent == current:
@@ -225,9 +225,9 @@ for fpath, keys in [(agent_file, given_keys), (counterpart, counterpart_keys)]:
f"Add '## {slug}' entry to agents/sources.md or remove '{slug}' from {rel} source_keys."
)
# --- Checks 4, 5, 6: Per-slug checks in agents/sources.md ---
# --- Checks 3, 4, 5: Per-slug checks in agents/sources.md ---
for slug in parse_h2_slugs(sources_content):
# Check 4: Contributing files exist (paths relative to plugin root)
# Check 3: Contributing files exist (paths relative to plugin root)
cf_value = parse_contributing_files(sources_content, slug)
if cf_value and not cf_value.startswith("(none"):
cf_files = [p.strip() for p in cf_value.split(",") if p.strip()]
@@ -241,7 +241,7 @@ for slug in parse_h2_slugs(sources_content):
f"Create '{cf_rel}' relative to the plugin root, or correct the path in agents/sources.md."
)
else:
# Check 5: Bidirectional — file should list slug in its source_keys
# Check 4: Bidirectional — file should list slug in its source_keys
with open(cf_abs) as f:
cf_content = f.read()
cf_fm, _ = parse_frontmatter(cf_content)
@@ -254,7 +254,7 @@ for slug in parse_h2_slugs(sources_content):
f"Add '{slug}' to the top-level source_keys frontmatter in '{cf_rel}'."
)
# Check 6: Research doc field required
# Check 5: Research doc field required
rd_value = parse_research_doc(sources_content, slug)
if rd_value is None:
emit_fail(