Claude Code, already fluent in Dotkernel.
dotboost is one directory you copy into a Dotkernel project. Claude arrives knowing where a module goes, which naming dialect the app uses and how its responses are built — and knowing which files it must never open.
$ git clone --depth 1 https://github.com/dotkernel/dotboost.git .dotboost && cp -r .dotboost/.claude .claude && rm -rf .dotboost
No git on the machine? Take the zip instead. Either way there is one more step — the executable bits.
Not an application. A configuration.
The repository is not a Dotkernel app you build on. Its entire payload is the .claude/ directory: permission rules, six hooks, a status line, a review subagent, ten /dk-* commands and seventeen skills.
Every skill detects the variant before it answers — API, Admin, Frontend, Light, Queue, or a project derived from one of them — and applies the matching dialect. Handler naming, authorization keys and response shape differ between them, and a wrong guess is the kind of mistake that survives review.
The first thing you see is the session-start briefing.
variant Dotkernel API namespace Api\ authorization RBAC via config/autoload/authorization.global.php branch feature/wallet-ledger feature docs documentation/features/ (14 docs) missing config/autoload/local.php — copy from .dist line endings ok (lf)
<project>/.claude/ ├── settings.json guardrails, hooks, status line ├── settings.local.json.example ├── statusline.sh 5h / 7d account usage ├── markdownlint.jsonc ├── hooks/ six bash hooks ├── agents/ the review subagent ├── commands/ ten /dk-* commands └── skills/ seventeen skills
Six hooks that run whether or not Claude cooperates
Skills are advice. Hooks are enforcement — they sit in front of the tool call, so a compound command cannot slip past them.
vendor/, migrations, dependency manifests, uploads, logs and key material. A blocked *.local.php edit is redirected to its .dist template.cd src && composer require foo.php -l on every PHP file Claude writes. Report-only.markdownlint-cli2 on every markdown file, against the shipped rule set. Silent when the binary isn't installed.Your credentials never enter the context window
This is the part worth adopting the file for. settings.json is committed and carries opinions, not only protection — sessions start in plan mode, so Claude proposes before it edits.
Never read
Read denies, not write protection. The contents are never sent at all.
- .env
- *.local.php
- config/autoload/local.php
- data/oauth/
Never written
Claude proposes the change in chat instead.
- composer.json
- composer.lock
- package.json
- vendor/
- node_modules/
- data/
- log/
- public/uploads/
- Migration/
Never run
Dependency changes and history rewrites stay a human decision.
- composer require
- composer update
- npm/yarn/pnpm install
- git push
- git reset --hard
- git clean
- rm -rf
Asks first
Reachable, but never silently.
- doctrine-migrations
- bin/cli.php
- mysql
- git commit
- git add
- config/pipeline.php
- phpstan.neon
- .github/
- CHANGELOG.md
Runs freely
The quality gate and read-only git, so a review or a fix doesn't stall on prompts.
- composer check
- cs-check
- cs-fix
- static-analysis
- test
- clear-config-cache
- dump-autoload
- vendor/bin/*
- php -l
- git status
- git diff
- git log
The ask and allow tiers are preference — override them per machine in settings.local.json, which is git-ignored, never in the shared file.
Ten commands for the work that repeats
Each one is a checklist Claude follows rather than a prompt you retype.
dot-maker first, manual wiring after.src/.Seventeen skills, loaded when the question calls for them
There is no routing table. Each skill's description decides whether it loads, so asking where a new Doctrine entity goes reaches for module structure rather than general framework knowledge.
One of them changes how Claude names packages, and it needs a line in your project's CLAUDE.md to fire reliably: the ladder runs already in composer.lock, then dotkernel/*, then laminas/* and mezzio/*, then a vetted community package, then hand-rolled code. Never a package name from memory.
- application-variants
- module-structure
- handler-naming
- doctrine-entities
- input-validation
- responses
- openapi
- feature-docs
- testing
- evolution-pattern
- security
- dot-maker
- core-submodule
- psr-standards
- qa-gate
- troubleshooting
- dependency-policy
Real usage in the status bar
Taken from the rate-limit payload Claude Code passes in on stdin — the same numbers /usage reports. Pure bash and awk, so it works in Git Bash on Windows.
~/project : Opus 5 ==> 5h:37% 2h14m left, resets @16:20 | 7d 61%
Install
The payload has to sit at the root of your project. Clone it or take the zip — same files either way.
Get .claude/ into the project
The clone is removed straight after the copy, so nothing nested is left for a git add . to trip over. Without git, the zip carries the dotfiles too.
$ cd <project> $ git clone --depth 1 https://github.com/dotkernel/dotboost.git .dotboost $ cp -r .dotboost/.claude .claude $ rm -rf .dotboost
Restore the executable bits
Nothing is committed executable, and a zip extracted on Windows carries no permission bits at all. The hooks and status line are invoked as bash <path> and run regardless; the dependency-policy sync script is called by its own name.
$ chmod +x .claude/hooks/*.sh .claude/statusline.sh \ .claude/skills/dependency-policy/scripts/*.sh $ echo '.claude/settings.local.json' >> .git/info/exclude
Paste the dependency policy into CLAUDE.md
A skill description decides whether a skill can load, not whether Claude stops to think before naming a package. That rule has to be always loaded, which means it lives in your project's own CLAUDE.md. The README carries the block to paste.
Verify
Start Claude Code in the project. /help should list the dk-* commands and the session hook should open with the briefing. Then test a guardrail: ask it to edit vendor/autoload.php, or to add a package to composer.json. Both should be refused, with the change proposed in chat instead.
If the project already has its own .claude/settings.json or commands/, merge by hand — same-named files are overwritten. To update later, run the install again over the top; that is why personal changes belong in settings.local.json.
Treat the skills as living documents
When a review turns up the same mistake twice, that is a missing line in a skill, not a Claude problem. Before adapting dotboost to a new Dotkernel application, spend an hour reading that repo and correcting the skills against what is actually there — a skill written from framework docs rather than the codebase produces confident wrong answers, which is worse than no skill.