Why: the relocation into gates.md and architecture.md moved text faster than it
verified it, and a review found eight assertions that do not survive contact
with the repo.
- gates.md cited docs/research/examples/, which does not exist; the tree is at
plugins/kyberforge/docs/research/examples/. The same wrong string survives at
ADR-0013:98, where it originated, and is tracked separately.
- gates.md's description-budget arithmetic was built on 23,427, a figure
ADR-0020 measured at f9b919d and pins there, and compared a name-inclusive
total against a description-only ceiling. Dropped rather than re-measured,
following the precedent this branch set for CONTEXT.md's token figure: a
second live copy is a second thing to go stale.
- gates.md listed "every boundary-clause routing target must resolve" as a hard
FAIL. skill-size-check.sh emits unresolved targets as SUGGESTION by default,
promotes to ERROR only when terminal and either route-notated or corroborated
by a resolving target in the same sentence, and reports INFO DID NOT RUN when
no universe resolves. Verified with five fixtures; replaced with a
three-verdict table.
- gates.md and README called `pre-commit run --hook-stage pre-push --all-files`
the whole push gate. check-release-needed.sh exits 0 unless
PRE_COMMIT_REMOTE_BRANCH is refs/heads/main, which only the real git hook
exports -- its own header comment titles this a "Known gap".
- "repo-defined" was loose: the two meta hooks are also declared here, and what
separates them is repo: meta from repo: local.
- architecture.md claimed `when:` appears in two of 39 skill sources. Exactly
one SKILL.md carries it; the second hit is a META.md. The likely origin is
skill-implementation-workflow.md:233, which claims META.md sits alongside
every skill when one exists in the whole tree.
- architecture.md said core/AGENTS.md is "deployed beside" CLAUDE.md.
deploy-manifest.sh sends them to ~/.claude/ and ~/.agents/ respectively; the
relation is import, not adjacency.
- gates.md's see-also cited ADRs as bare stems where its neighbours use paths.
Implementation notes: architecture.md's closing pointer sent readers to the
published description "for what a consumer actually gets", which was true
against an enumeration and is not after ADR-0021. It now names the boundary
relationship and points at the skills tree and README for an inventory. README's
bin bullet gains caveman and zoom-out, since ADR-0021 leaves it the only place
an inventory lives.
Impact: 16/16 pre-push hooks pass. Deliberately not fixed here and tracked
separately: the 12 pre-commit-stage hooks gates.md does not document, its own
SentenceOpenerThereIs violation, and README's missing scripts/install.sh step.
Refs: #105
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TmFqzpuExLJv3m114XVE9w
132 lines
8.8 KiB
Markdown
132 lines
8.8 KiB
Markdown
# 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, MCP servers, 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, and pre-commit hook authoring and running (`pc-author` / `pc-run`)
|
|
- **gitea** — issues, pull requests, labels, milestones, releases, branches, files
|
|
- **core** — authoring and auditing a repo's `AGENTS.md` and 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 | Four pre-push hooks shell out to it (`apm-marketplace-check`, `apm-audit-ci`, `apm-pack-check-clean`, and `check-plugin-content-sync` via `scripts/sync-plugin-content.sh`) | The `apm-install` skill, or `curl -sSL https://aka.ms/apm-unix \| sh`. Verify with `apm --version` |
|
|
| `jq` | Required by `scripts/check-manifests.sh` and `scripts/sync-plugin-content.sh`, both pre-push | Your package manager |
|
|
| `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-plugins` and `validate-marketplace` pre-push hooks | 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 sync` is needed.** The `Kyberforge` styles are committed under `plugins/kyberforge/.apm/skills/{skill-audit,agent-audit}/assets/vale/styles/`, not downloaded packages (ADR-0014).
|
|
|
|
## Setup
|
|
|
|
Run these in order, from the repo root.
|
|
|
|
```bash
|
|
# 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, materializes `apm_modules/` (which stays gitignored), and also configures the `obsidian` MCP server into the repo's `.mcp.json`.
|
|
|
|
**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 ships a `SessionStart` hook that runs `apm outdated` at startup (~0.7s) and, when something is behind, runs `apm update --yes` and asks the host to re-scan skills (~10.4s).
|
|
|
|
That rewrites `apm.lock.yaml` — an unexplained modification to it after opening a session is expected, not a bug. Commit or discard it deliberately.
|
|
|
|
Note the difference between the two commands:
|
|
|
|
- `apm install` deploys from `apm.lock.yaml`. It does **not** pick up remote changes.
|
|
- `apm update` re-resolves refs. This is the command that pulls in a merged `.apm/` edit.
|
|
|
|
## Running tests
|
|
|
|
```bash
|
|
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:
|
|
|
|
```bash
|
|
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`](docs/spec/gates.md) for what each hook enforces and why.
|
|
|
|
**Offline?** Exactly two pre-push hooks need the network, because root `apm.yml`'s marketplace contains one remote package entry that must be resolved with `git ls-remote`:
|
|
|
|
```bash
|
|
SKIP=apm-marketplace-check,apm-pack-check-clean git push
|
|
```
|
|
|
|
Skip **only** those two. The remaining pre-push hooks are real local checks and pass offline; adding one of them to `SKIP` disarms it silently.
|
|
|
|
## Editing plugin content
|
|
|
|
`plugins/<name>/.apm/` is the only hand-edited source for plugin content — skills, agents, commands, instructions, extensions, and hooks. The flat `plugins/<name>/{skills,agents,commands,instructions,extensions}/` directories, the merged `hooks/hooks.json`, and every `plugin.json` / `marketplace.json` manifest are generated. Nothing labels a generated file as generated, so check the path before you edit; an edit to the mirror is discarded by the next sync and reported as drift by the `check-plugin-content-sync` pre-push hook.
|
|
|
|
Hand-authored material that is *not* an `.apm/` primitive — `README.md`, `docs/`, `bin/`, `sources.md`, `.mcp.json` — lives at the plugin **root** and is untouched. Never place such a file inside a mirrored directory: the sync removes the destination before every copy, so it is deleted with no drift report.
|
|
|
|
Full detail in [`docs/spec/architecture.md`](docs/spec/architecture.md).
|
|
|
|
## For external consumers
|
|
|
|
Install a plugin natively from the marketplace manifests:
|
|
|
|
```bash
|
|
claude plugin install <name>@holocron
|
|
```
|
|
|
|
Or 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`.
|
|
|
|
## Where to go next
|
|
|
|
- [`AGENTS.md`](AGENTS.md) — the rules for AI agents working in this repo
|
|
- [`CONTEXT.md`](CONTEXT.md) — domain language; read at the start of every session here
|
|
- [`docs/spec/architecture.md`](docs/spec/architecture.md) — directory structure, install pipeline, provider model
|
|
- [`docs/spec/gates.md`](docs/spec/gates.md) — the enforcement gates in depth
|
|
- [`docs/adr/`](docs/adr/) — architectural decisions; read before proposing structural changes
|
|
- [`docs/VISION.md`](docs/VISION.md) — where this is going
|
|
- [`LESSONS.md`](LESSONS.md) — things that went wrong once and should not again
|