Why: this audit was written read-only and its scope estimates proved systematically optimistic. Ten open findings with claimed yield were re-verified against the files by independent agents. One premise of ten survived, and the headline figure was wrong in at most eight of the ten. Implementation notes: per-finding verification notes on 11, 16, 20, 22, 24, 27, 28, 33, 34 and 36. Finding 5 marked not proceeding, on the same grounds as finding 3 -- its six suites are split by failure class, not ADR section, and five of the six headers name the incident they guard. Finding 18 re-scoped and folded into finding 22 under three exemptions (audit criteria, assets/templates and sourced spec restatement, the last now carrying a decidable test rather than resting on the presence of source_keys). Finding 32 closed with its premise corrected. Section 8 questions updated where measurement answered them: ADR-0012 is moot, git/gitea granularity fails an enforced gate at 4.9x, and the external-consumer question has its evidence but awaits a decision. New section 10 records the wave, the recurring failure mode behind six wrong findings, and where the remaining opportunity actually sits. The wave's own notes were then re-verified by a second independent round, and this commit carries those corrections. The notes had an error rate comparable to the findings they corrected. Four errors changed a verdict. Finding 11's note anchored its search at column 0 and so missed every source_keys carrier nested under metadata:, producing "172 carriers" (196), "zero of 40 SKILL.md files carry source_keys" (28 of 39) and "check 2 is dead code" (live, with bats coverage); its double-counting accusation was a misreading of the word "plus" and is withdrawn. Finding 28's note claimed 2,740 lines "has never matched any commit" -- it is exact ata3e721e, the unique commit of the 67 touching docs/adr/ that yields it, and where all of the finding's headline figures reproduce simultaneously; the finding went stale, it was not fabricated. Finding 20's note argued the gitea split was blocked a fortiori by ADR-0011, which inverts that ADR's reasoning (its objection is to a boundary being crossed, not to bundle size) -- withdrawn and replaced with the same objection aimed at the correct seam, in the note and in section 8. Finding 18's "sourced spec restatement" exemption collided with finding 20's own salvage recommendation in the same commit and now carries a test that separates them. Bookkeeping corrected throughout: the dangling docs/HUMANS.md path is five occurrences across three files, not four (the sentence enumerated five while stating four); finding 16'sc8a7c9echronology was inverted, and its resolver core is 549 executable lines, not 357, making it 2.7x the proposed budget rather than 1.8x; finding 24's Q1-Q5 coverage is 20 tests and ~67%, not 24 and ~76%; finding 22's estimate is ~150-180 lines with its components summing, and its RED/GREEN rebuttal no longer depends on ignoring the two diagrams the finding most plausibly named; finding 27's preamble is 43 words; finding 28's proposal is a wash (+5 to -1) rather than a firm +5; finding 32's citation is architecture.md:22 and its net is 6 lines. Section 10's table reconciled against every corrected note. Impact: no code, gate or behaviour changes. Two defects are flagged for independent fixing -- the deployed core/instructions/governance.md cites docs/HUMANS.md, which does not exist, in five places across three files; and apm update on this branch resolves against main and would restore the obsidian MCP server removed inc96ca9c, via the regenerated repo-root .mcp.json, which is gitignored and so would not appear in git status. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YR2CjVumUbEGWcMikcoXBD
holocron
The global AI development configuration repository — the authoritative source for agent definitions, skills, workflows, and prompts across all projects. Built as a homelab tool intended to scale to professional environments.
Content ships as six installable plugins, each an apm (Agent Package Manager) package. This repo consumes its own plugins through apm, so the working copy runs the same released content every other consumer gets.
Repo layout
| Path | What it holds |
|---|---|
plugins/ |
Six apm packages — bin, core, git, gitea, kyberforge, lint — each carrying skills, and where relevant agents, hooks, and bundled assets |
providers/claude-code/ |
Claude Code adapter, deployed to ~/.claude/ via scripts/install.sh |
core/ |
Provider-agnostic always-on content — core/AGENTS.md and core/instructions/ |
docs/ |
Specs (docs/spec/), architectural decisions (docs/adr/), governance, research, and notes |
scripts/ |
Install, sync, and check scripts used by the git hooks |
tests/ |
run-tests.sh, run-bats.sh, the test-*.sh suites, and the bats submodules |
The six plugins:
- kyberforge — skills and agents for creating, maintaining, and managing a Claude Code / Copilot CLI plugin marketplace
- git — conventional commits, branches, history, submodules, worktrees, remotes, pre-commit hook authoring and running (
pc-author/pc-run), and an interactive router (git-workflow) - gitea — issues, pull requests, labels, milestones, releases, branches, files, and an interactive router (
gitea-workflow) - core — authoring and auditing a repo's
AGENTS.mdand the provider adapter files that defer to it - lint — configuring and running linters
- bin — cross-cutting workflow skills not yet split into a focused plugin: research, documentation, TDD, prototyping, triage, diagnosis, architecture review, requirement grilling, compressed output (
caveman), and re-orienting mid-task (zoom-out)
Prerequisites
Install all of these before setting up. Each one is a hard dependency of a git hook or a script — several fail with an unhelpful "command not found" if missing.
| Tool | Why | Install |
|---|---|---|
apm CLI |
Two pre-push hooks shell out to it (apm-audit-ci and apm-pack-check-clean) |
The apm-install skill, or curl -sSL https://aka.ms/apm-unix | sh. Verify with apm --version |
python3 + PyYAML |
Required by scripts/skill-size-check.sh (the skill-size-check pre-commit hook), which reads folded YAML frontmatter |
python3 is usually present — pre-commit is itself a Python application. pip install pyyaml if the hook reports PyYAML missing |
vale |
Required by the vale-audit-prefilter-skill / -agent pre-commit hooks and the check-vale-style-sync pre-push hook |
brew install vale (macOS), snap install vale (Linux), choco install vale (Windows), or https://vale.sh/docs/vale-cli/installation/ |
claude CLI |
Required by the validate-marketplace pre-push hook |
Claude Code |
Two notes worth reading before you skip one:
- PyYAML is a hard requirement, not an optional accelerator. The hand-rolled fallback frontmatter reader was removed deliberately: a reader that mis-parses an unfamiliar scalar shape reports a clean pass on a file it never measured.
- No
vale syncis needed. TheKyberforgestyles are committed underplugins/kyberforge/.apm/skills/{skill-audit,agent-audit}/assets/vale/styles/, not downloaded packages (ADR-0014).
Setup
Run these in order, from the repo root.
# 1. Deploy this repo's own skills and agents
apm install
# 2. Install the git hooks — all three stages
pre-commit install -t pre-commit -t commit-msg -t pre-push
apm install deploys the six plugins into .claude/skills/ and .claude/agents/. Both are gitignored install output, not authoring source — plugins/<name>/.apm/ remains the only place to edit. It needs the network and materializes apm_modules/ (which stays gitignored).
Git hooks must be wired for all three stages. This repo's .pre-commit-config.yaml has no default_install_hook_types, so a plain pre-commit install silently skips commit-msg (Conventional Commits) and pre-push (the full gate) — the -t flags above are not optional. The pc-run skill handles this and the troubleshooting around it, if you would rather not remember the flags.
Keeping the install current
The six dependencies in root apm.yml are unpinned against the default branch, so deployed skills go stale whenever anyone merges. kyberforge's SessionStart hook keeps the install current automatically on launch, rewriting apm.lock.yaml in the process — an unexplained modification to it after opening a session is expected, not a bug; commit or discard it deliberately. Mechanism and rationale: docs/adr/0019-session-start-hook-keeps-the-apm-install-current.md.
Note the difference between the two commands:
apm installdeploys fromapm.lock.yaml. It does not pick up remote changes.apm updatere-resolves refs. This is the command that pulls in a merged.apm/edit.
Running tests
bash tests/run-tests.sh # every test-*.sh script plus the bats suite
bash tests/run-tests.sh --bats-only # just bats
The first run auto-initializes the bats submodules; no manual git submodule update needed.
A suite that exits 77 because a dependency is missing is reported as SKIPPED and does not fail an ad-hoc run. It does fail under --strict (equivalently RUN_TESTS_STRICT=1), which is how the pre-push hook invokes it — at pre-push, a skip means one of the prerequisites above is absent on this machine, and the gate would otherwise report success having run fewer suites than it appears to. The strict failure names each skipped suite and what to install.
Before pushing
Run the pre-push gate locally in one command:
pre-commit run --hook-stage pre-push --all-files
One caveat: check-release-needed is a silent no-op under this invocation. It exits 0 unless
PRE_COMMIT_REMOTE_BRANCH is refs/heads/main, and pre-commit exports that only from the real
pre-push git hook during an actual git push — so the hook reports Passed having checked nothing.
Every other pre-push hook does run.
See docs/spec/gates.md for what each hook enforces and why.
Offline? No pre-push hook needs the network: root apm.yml's marketplace has no remote package entries (the last one, mattpocock-skills, was removed), so apm-pack-check-clean resolves everything from local sources. All pre-push hooks pass offline.
Editing plugin content
plugins/<name>/.apm/ is the only hand-edited source for plugin content — the root marketplace.json manifest is generated by apm pack, and a hand-edit there is reported as drift by apm-pack-check-clean. Hand-authored material that is not an .apm/ primitive (README.md, docs/, bin/, sources.md) lives at the plugin root instead.
Full model, including what's exempt and why: docs/spec/architecture.md.
For external consumers
Consume the packages through apm, the way this repo does — declare them as dependencies.apm git+path entries against the holocron remote and run apm install. apm is the only supported install path.
Where to go next
AGENTS.md— the rules for AI agents working in this repoCONTEXT.md— domain language; read at the start of every session heredocs/spec/architecture.md— directory structure, install pipeline, provider modeldocs/spec/gates.md— the enforcement gates in depthdocs/adr/— architectural decisions; read before proposing structural changesdocs/VISION.md— where this is goingLESSONS.md— things that went wrong once and should not again