dotkernel-core-submodule
Use whenever a change touches the Core layer of a Dotkernel project — adding or editing a Doctrine entity, repository, enum, DBAL type, fixture, migration or shared service — or when deciding whether
SKILL.md.claude/skills/dotkernel-core-submodule/SKILL.md
GitHubThe shared Core layer
Applies to
Projects: - Dotkernel API
- Dotkernel Admin
Packages: - none
Dotkernel's headless platform is a set of projects over one database: an API as the root, and optionally an Admin for management. The arrangement is flexible — two APIs and one Admin is equally valid.
src/Core is the codebase they share, so one change to a shared entity or service propagates
rather than being copy-pasted into each project. The stock API and Admin ship the same Core
modules — Admin, App, Security, Setting, User.
The stock Frontend, Light and Queue have no Core: Frontend keeps its entities inside its own
modules, and Light and Queue have no persistence. A derived project can adopt Core, but do not
assume it has.
In API and Admin, src/Core ships as an ordinary module, designed as the starting point for
extraction into a git submodule. Treat it as if it already were one.
Rules for Core code
- Core is the only place that manages database entities. All Doctrine entities,
repositories, enums and DBAL types live under
src/Core/src/<Module>/src/. - Core must never depend on a project namespace. No
Api\…,Admin\…,Frontend\…imports; nothing HTTP-request-shaped, no HAL, no forms. If a Core service must signal failure, throw a Core-level exception or return null and let the application layer translate it. - Anything in Core is potentially consumed by every other project. Before changing a Core signature, ask whether it breaks the siblings. Prefer additive changes; deprecate rather than rename.
- Not everything shared-looking belongs in Core. Logic used by exactly one project stays in that project's module. Core is for genuinely common code.
- Migration directories under Core are generated — never hand-edit.
Splitting a change
A typical feature spans both layers:
src/Core/src/Book/src/Entity/Book.php ← schema, invariants, accessors
src/Core/src/Book/src/Repository/BookRepository.php ← query builders
src/Book/src/Service/BookService.php ← use-case orchestration
src/Book/src/Handler/Book/…Handler.php ← HTTP / presentation
Both layers get their own ConfigProvider, and both are registered in config/config.php.
Creating the submodule
Create a new git repository for the Core code, then from the project root:
git submodule add <url> src/Core
Git writes .gitmodules, mapping the URL to the local path so it can clone, update and track it.
Delete the existing src/Core directory before adding the submodule to a second project.
No Dotkernel project ships .gitmodules out of the box — it only exists once you have
isolated Core into its own repository.
Day-to-day mechanics
Cloning a project that has one:
git submodule init
git submodule update
# or: git clone --recurse-submodules <url>
Committing Core changes — from inside the submodule directory, which is its own repository:
cd src/Core
git add .
git commit -m "…"
git push
Then, in the parent repository, commit the updated submodule pointer:
cd ../..
git add src/Core
git commit -m "Bump Core submodule"
Skipping that second step is the classic failure: teammates pull and still get the old Core.
Working rules for an agent
- Before editing Core, state that the change is cross-project and name the likely consumers.
git submoduleandgit pushare in the deny tier and refused by theguard-bash.shhook, approval or not — never try to run them. Give the user the exact commands to run instead.git addandgit commitprompt for approval; run them only when the user has asked for the commit.- If
.gitmodulesexists, do not stage Core content changes from the parent repo — they belong to the submodule's own history. - Schema changes need a migration, generated not written, and applied by every project on that database.
- A schema-validation CI job will catch entity/migration drift.
Why this design
Consistency across projects, one place to fix a bug, work splittable across developers without merge storms, easier onboarding, and a platform that scales by adding projects that all speak to the same Core-defined model.