audit: full test-run — 3 fixes applied, 4 untracked items, kyberforge improvements needed #2
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Overview
A complete test audit was run on this session (2026-06-21). All automatable checks were executed via parallel subagents. Three issues were fixed inline. Four new issues were found that are not yet tracked. The kyberforge plugin has several follow-on improvement opportunities. This issue is the handoff document for a follow-up session.
Process followed
1. Discovery
Surveyed the repo to identify all runnable checks before launching agents:
tests/*.sh— shell test scriptsscripts/check-manifests.sh— manifest validator.agents/evals/andplugins/kyberforge/*/evals/eval.yaml— eval filesplugins/kyberforge/skills/marketplace-architect/scripts/— plugin utility scriptsclaude plugin validate— Claude Code plugin manifest validator (discovered as a gap mid-session)2. Parallel execution
Launched 4 subagents in parallel (first wave):
check-manifests.sh,bash -nsyntax, shellcheckThen a 5th agent (second wave) after user flagged the gap:
marketplace-architect/scripts/test_scripts.sh,inventory.sh,validate.sh, hitl-loop template syntax checkThen a 6th agent after confirming
claude plugin validatehad not been run:claude plugin validate(normal +--strict) on kyberforge plugin and both marketplace manifests3. Fix and verify
claude plugin validate --strictafter fixes to confirm both targets now passResults — what passed
marketplace-architect/scripts/test_scripts.sh— 18 casesscripts/check-manifests.shbash -nsyntax — all scripts and test fileseval.yamlfilesgitleaks detect --no-git(working tree)claude plugin validate plugins/kyberforgeclaude plugin validate .claude-plugin/marketplace.jsonclaude plugin validate .github/plugin/marketplace.jsonTests skipped by design (require live Claude session or modify the system):
tests/test-install.sh— modifies~/.claude/; needs a clean isolated environmenttests/test-governance-layer.sh— requires a live interactive Claude sessiontests/test-instructions-and-docs.sh— requires a live interactive Claude sessionFixes applied this session
Fix 1 —
install.shSC2115:rm -rfwithout:?guardFile:
scripts/install.shline 42Severity: Real risk (low probability, high blast radius)
Before:
After:
Why it's a bug: If
$skill_namewere ever unset or empty (e.g. unexpected glob expansion behaviour), this expands torm -rf "$skills_dest/"— wiping the entire skills destination directory.set -euo pipefailat the top of the script reduces the probability (unset variable would abort), but the:?guard is the correct defensive pattern and what shellcheck SC2115 requires. The cost of the fix is zero; the blast radius of the failure is not.Fix 2 —
kyberforge/.claude-plugin/plugin.jsonmissingversionfieldFile:
plugins/kyberforge/.claude-plugin/plugin.jsonSeverity: Strict-mode validation failure
Before:
After:
Why it's a bug:
claude plugin validate --stricttreats a missingversionfield as an error (exit 1). Any CI pipeline using strict mode would fail. The field is documented as recommended (semver) in the plugin manifest spec.Fix 3 —
agents/README.mdtreated as an agent definition by the validatorFile:
plugins/kyberforge/agents/README.md→ moved toplugins/kyberforge/docs/adding-agents.mdSeverity: Strict-mode validation failure
Why it's a bug:
claude plugin validatescans all.mdfiles in theagents/directory and expects them to be agent definitions with YAML frontmatter. The file was a contributor guide explaining how to add agents to the plugin — not an agent definition. Kyberforge currently ships no agents, so the agents/ directory is now correctly empty. Moving the file todocs/preserves the content without confusing the validator.Untracked issues — require follow-up
U1 — Gitleaks false positive blocks pre-commit hook on all machines
File:
docs/research/ai-coding-factory/ai-coding-factory-session.md:90Rule triggered:
generic-api-keyMatch:
Token routing: Haiku/Sonnet/OpusWhy false positive: Plain prose in a research document describing Claude model tier routing. The word "Token" followed by a slash-delimited string triggers the entropy rule. No credential present.
Impact: The pre-commit gitleaks hook will block any commit on any machine where gitleaks is installed. First introduced in commit
ace8b53(2026-05-16).Fix: Add an allowlist entry to
scripts/gitleaks.toml:Or use the fingerprint-based allowlist if the gitleaks version supports it.
U2 —
write-skilleval asserts deprecated 8-section body formatFile:
plugins/kyberforge/skills/write-skill/evals/eval.yamllines 41–49Issue: The
output-has-all-sectionstest case asserts that output contains## Roleand## When to use / When not to use. Both sections were dropped from the authoring standard in the write-skill Phase 1 Refactor (2026-05-18). A skill that correctly follows the current standard will false-fail this test.Fix: Update the test to assert the current 6-section structure: Required inputs, Constraints, Process, Output format, Failure handling, Self-check. Remove assertions for
## Roleand## When to use / When not to use.Note: Pre-0019 cleanup item #3 says "run write-eval against write-skill to extend coverage" but does not specifically note this staleness. The stale assertion is a bug in the existing eval, not just a coverage gap.
U3 —
improve-codebase-architectureskill uses../relative paths (plugin-safety risk)File:
.agents/skills/improve-codebase-architecture/SKILL.mdlines 68 and 70Paths referenced:
../grill-with-docs/CONTEXT-FORMAT.md../grill-with-docs/ADR-FORMAT.mdCurrent status: Both files exist on disk (
CONTEXT.mdprinciple: verified, not assumed). No bug today.Risk: CONTEXT.md states that skills inside plugins are self-contained and cannot reference files outside their own directory after install-time caching. If this skill is ever packaged into a plugin, these relative paths silently break — the referenced files would not be present. The
inventory.shcross-reference scanner caught this (11../warnings across skill files).Fix: Either make the skill self-contained (inline the relevant content from those files) or add a note to the Chunk 3 rebuild task for this skill flagging the dependency.
U4 —
improve-codebase-architecture/scripts/cross-reference warnings (11 total)inventory.shfrom marketplace-architect reported 11 cross-reference warnings for../paths across.agents/skills/files. U3 above is the most concrete example. A full audit of all 11 is needed to determine which are in files already scheduled for Chunk 3 rebuild (acceptable — they will be rewritten) vs. which are in post-refactor skills that should be self-contained.Files to check: Run
bash plugins/kyberforge/skills/marketplace-architect/scripts/inventory.shand review the cross-reference section.Already-tracked items confirmed in this audit
write-docsstale frontmatter + old 8-section structurewrite-evalstale frontmatter + old 8-section structureshellcheckSC2034 false positives indeploy-manifest.shsource; no fix neededKyberforge plugin — improvement opportunities identified
These are not bugs but quality gaps discovered during the audit. Relevant for the kyberforge improvement workstream the user mentioned.
write-evalneeds refactor to 6-section standard — currently follows the old 8-section format with Role + When/Not sections and provenance fields in SKILL.md frontmatter. Pre-0019 cleanup item #2. Should usewrite-skillto author the refactored version.write-skilleval stale assertions — see U2 above.agents/directory is now empty — Fix 3 moved the only file out. The rootplugin.jsonstill has"agents": "agents/". This reference should either be removed or the directory should house actual agent definitions if/when kyberforge adds agents. Low priority but leaves a dangling reference.scripts/validate.shandscripts/inventory.share not integrated into the shell test suite —test_scripts.shcovers unit tests for these scripts but does not run them against the live repo as part oftests/. Theinventory.shcross-reference output is useful for ongoing quality checks and could be atests/test-inventory.shthat asserts zero../warnings in post-refactor skills.No CI pipeline runs
claude plugin validate --strict— All the plugin validation work done in this session was manual. A CI gate (Chunk 6 scope) should run this automatically on every push that touchesplugins/or.claude-plugin/.plugin-createassets may need updating — Theassets/plugin-template/agents/README.md(the template for new plugins) is a separate file from the one moved in Fix 3. Verify it still reflects the correct convention for agent directories and that new plugins scaffolded byplugin-createwill also passclaude plugin validate --strict.Recommended follow-up actions (priority order)
write-skilleval stale assertions; prevents false eval failures before 0019 work begins.bash scripts/install.shin an isolated environment, runclaude plugin validate --stricton kyberforge, confirm all three fixes hold.inventory.sh, triage the 11../cross-reference warnings; close or create follow-up issues per skill.claude plugin validate --strictto the CI spec — note indocs/research/governance_principles/CONTROLS.mdor the Chunk 6 grill as a required gate forplugins/changes.Session context
mainat commit117e07ftest-governance-layer.sh,test-instructions-and-docs.shtest-install.shclaude plugin validatewas not in the initial check sweep — discovered as a gap when user flagged it; added in second waveCommits from this session
All fixes described in this issue have been committed and pushed to
main.ce7dd15fix(hooks): pass-xto shellcheck and fixsource=directive path — pre-existing bug exposed wheninstall.shwas first staged post-audit247bd4afix(kyberforge): addversionfield to claude-code plugin manifesta3ff72cfix(kyberforge): moveagents/README.mdtodocs/— not an agent definition34c93d9chore(docs): remove.gitkeepplaceholders fromdocs/ard/anddocs/bug/Note on Fix 1 (
install.shSC2115:?guard): this change was folded into commitce7dd15alongside the shellcheck-xfix, since both touchedinstall.shand both were required to get the hook to pass.Post-push CI: all remote hooks passed — 126 install tests, 23 governance checks, 5 manifest checks, 34 hook setup tests. All green.
Still open from this issue: U1 (gitleaks allowlist), U2 (write-skill eval stale assertions), U3/U4 (
../cross-reference audit), and the kyberforge improvement items. None are blocking current work.Test suite gap analysis — handoff for follow-up session
A structural audit was run against
docs/research/governance_principles/CONTROLS.mdto identify what the test suite is missing. Seven gaps are immediately actionable (no CI required). Five more are Chunk 6 scope.docs/ROADMAP.mdhas been updated with this breakdown under the Governance workstream section.Immediately actionable — 7 items, no Chunk 6 dependency
Work these in order. Items 2–4 depend on item 1 being resolved first.
1. Fix U1: gitleaks false positive before anything else
Why first: any gitleaks scan test will fail until this is resolved. Pre-commit hook blocks commits on all machines with gitleaks installed.
File:
scripts/gitleaks.tomlMatch:
Token routing: Haiku/Sonnet/Opusindocs/research/ai-coding-factory/ai-coding-factory-session.md:90triggersgeneric-api-key(entropy match on "Token"). Not a credential.Fix:
Verify:
gitleaks detect --source . --config scripts/gitleaks.tomlexits 0.2.
tests/test-gitleaks-scan.sh— run scan against the live repoGap:
test-setup-gitleaks.shtests that the setup script works; nothing tests that the scan itself passes. The U1 false positive went undetected until a manual audit.What to write:
gitleaks detect --source . --config scripts/gitleaks.toml --no-gitand assert exit 0gitleaks detect --source . --config scripts/gitleaks.toml(with git history) and assert exit 0scripts/gitleaks.tomlhas at least one[allowlist]block (regression guard — a config with no allowlist is a config that hasn't been validated)Requires: item 1 done first.
3.
tests/test-plugin-validate.sh—claude plugin validate --stricton all targetsGap: Discovered mid-session as a manual check. Not in
tests/and not in the pre-push hook.What to write:
claude plugin validate plugins/kyberforge --strict→ assert exit 0claude plugin validate .claude-plugin/marketplace.json --strict→ assert exit 0claude plugin validate .github/plugin/marketplace.json --strict→ assert exit 0Also: add
claude plugin validate .claude-plugin/marketplace.json --strictto the pre-push hook inscripts/setup-hooks.sh(and update.git/hooks/pre-push). Current pre-push only runscheck-manifests.sh.4.
tests/test-hook-integrity.sh— verify installed hook, not setup scriptGap:
test-setup-hooks.shtests thatsetup-hooks.shproduces the correct hook. Nothing tests that the hook is actually installed and active — the control CONTROLS.md calls out for monthly verification.What to write:
.git/hooks/pre-commitexists and is executable.git/hooks/pre-commitcontains the gitleaks marker (# managed by setup-gitleaks.sh).git/hooks/pre-commitcontains the shellcheck/jq/yq/SKILL.md marker (# managed by setup-hooks.sh).git/hooks/commit-msgexists and is executable.git/hooks/pre-pushexists and is executable.git/hooks/pre-pushreferencescheck-manifests.sh5.
tests/test-inventory-crossrefs.sh— assert clean cross-reference outputGap:
marketplace-architect/scripts/test_scripts.shunit-testsinventory.shbut nothing runs it against the live repo to catch../path warnings.What to write:
bash plugins/kyberforge/skills/marketplace-architect/scripts/inventory.shfrom repo rootgitleaks,neuledge-context,write-docs,write-skill(in.agents/skills/), plus all kyberforge plugin skills.caveman,diagnose,grill-me,grill-with-docs,improve-codebase-architecture,prototype,tdd,to-issues,to-prd,triage,zoom-out.Also resolves U4 from the original issue — the triage of the 11
../warnings.6. Extend
test-governance-layer.sh— verify controls are enforced, not just files presentGap: Current checks verify
governance.md,ai-constitution.md,HUMANS.mdexist and contain expected content. CONTROLS.md requires that the controls themselves are in place.Add to the existing script:
.git/hooks/pre-commitexists and is executable (gitleaks wired)gitleaksis in$PATH(pre-commit hook is effective, not silently skipped)claude plugin validate .claude-plugin/marketplace.json --strictexits 0 (plugin manifests meet the spec)scripts/gitleaks.tomlhas at least one[allowlist]block (scan has been validated)7.
tests/run-all-tests.sh— single entry point for all testsGap: No way to run everything with one command. Required for CI integration (Chunk 6) and useful now.
What to write:
Chunk 6 CI gaps — 5 items, blocked on CI pipeline
These require a
.gitea/workflows/CI pipeline. Document them now so the Chunk 6 grill starts with a concrete list.When the Chunk 6 grill begins, read this issue alongside
docs/research/governance_principles/CONTROLS.mdanddocs/ROADMAP.md(Governance workstream section).Session state when this comment was written
mainat commit34c93d9docs/ROADMAP.mdupdated with pre-Chunk 6 test work and Chunk 6 CI gaps (same session, not yet committed)docs/ard/anddocs/bug/directories removed (.gitkeepcommitted in34c93d9)U1 resolved —
ac8235cU1 (gitleaks false positive) fixed in commit
ac8235c.What was fixed:
docs/ROADMAP.mdnow documents theToken routing: Haiku/Sonnet/Opuspattern, which itself triggered the samegeneric-api-keyrule during the commit that added the test suite gap analysis. The false positive became self-blocking.scripts/gitleaks.toml(source) and.gitleaks.toml(deployed root copy read by the hook) were out of sync — the deployed file already had adocs/research/.*path allowlist (covering the original finding) but the source did not. Both files are now aligned with a shared allowlist coveringdocs/research/.*anddocs/ROADMAP\.md.Side-effect discovered:
scripts/gitleaks.tomland.gitleaks.tomlwere tracking different allowlist states. Anyone runningsetup-gitleaks.shwould have overwritten the deployed file with the stale source, losing the existingdocs/research/.*allowlist. Now in sync.U1 is fully closed. The
test-gitleaks-scan.shtest (item 2 in the previous comment) can now be written without a prerequisite blocker.Additional finding: gitleaks config sync is a recurring risk
Discovered while committing the ROADMAP update (the commit itself was blocked by the false positive pattern appearing in ROADMAP.md).
The structural problem:
scripts/gitleaks.toml(source, tracked in git) and.gitleaks.toml(deployed root copy, also tracked in git) are two separate files that are supposed to stay in sync —setup-gitleaks.shdeploys the source to the root. Found in this session with different allowlist states: the deployed.gitleaks.tomlhad adocs/research/.*path allowlist (suppressing the original false positive); the sourcescripts/gitleaks.tomldid not.Current risk: anyone running
setup-gitleaks.shin this repo will overwrite.gitleaks.tomlwith the stale source, silently removing the allowlist and re-exposing the false positive as a blocking pre-commit failure. The two files were synced in commitac8235c— but the underlying mechanism that caused the drift is still in place.Root cause:
setup-gitleaks.shis designed for deploying to other repos (project setup). When run in this repo, it overwrites a tracked file. There's no divergence check and no merge — pure overwrite.Options for the follow-up session (pick one):
Merge rather than overwrite — update
setup-gitleaks.shto detect when.gitleaks.tomlalready exists and merge rather than overwrite. Git-style: warn on divergence, require explicit--forceto overwrite. Cleanest long-term fix.Stop tracking
.gitleaks.tomlin git — add.gitleaks.tomlto.gitignore; treat it as a generated file that always comes fromsetup-gitleaks.sh. Pro: no sync burden. Con: every machine must runsetup-gitleaks.shbefore the allowlist is active. The pre-commit hook would be the backstop — and the pre-commit gitleaks block references the config by auto-discovery (no--configflag), so the root file must exist.Remove
scripts/gitleaks.tomlas a separate source — put the canonical config directly at.gitleaks.toml(tracked), and updatesetup-gitleaks.shto copy from the repo root rather than fromscripts/. Con: couples the global install script to the repo layout.Recommended: Option 1. It's the only one that preserves both the deploy-to-other-repos use case and the tracked-source use case without a sync burden.
Also note: the pre-commit hook generated by
setup-gitleaks.shrunsgitleaks git --staged --redact -vwithout a--configflag. Gitleaks auto-discovers.gitleaks.tomlat the repo root — which is why the allowlist works. But this auto-discovery assumption is fragile: if.gitleaks.tomlis absent (e.g. first checkout before running setup), the hook runs with the default config, and the false positive blocks the commit. A--config scripts/gitleaks.tomlflag in the hook would be more explicit and wouldn't depend on the root file existing.