Audit and enforce the core/client boundary in multi-client projects. Detects where shared platform code is tangled with client-specific code, finds hardcoded client checks, config files that replace instead of merge, scattered client code, migration conflicts, and missing
Installs just this skill. Get the whole plugin for auto-invocation.
โก How it fires
How this skill gets triggered: by you, by Claude, or both.
Fires itselfClaude auto-loads it when your prompt matches the work.
You can call itInvoke it directly when you want it.
Slash command/fork-discipline
๐๏ธ Context preview
The summary Claude sees to decide when to auto-load this skill.
Audit and enforce the core/client boundary in multi-client projects. Detects where shared platform code is tangled with client-specific code, finds hardcoded client checks, config files that replace instead of merge, scattered client code, migration conflicts, and missing
๐ Stats
Stars940
Forks96
LanguagePython
LicenseMIT
๐ฆ Ships with jezweb-skills
</> SKILL.md
fork-discipline.SKILL.md
---name: fork-discipline
description: "Audit and enforce the core/client boundary in multi-client projects. Detects where shared platform code is tangled with client-specific code, finds hardcoded client checks, config files that replace instead of merge, scattered client code, migration conflicts, and missing extension points. Produces a boundary map, violation report, and refactoring plan. Optionally generates FORK.md documentation and restructuring scripts. Triggers: 'fork discipline', 'check the boundary', 'is this core or client', 'platform audit', 'client separation', 'fork test', 'refactor for multi-client', 'clean up the fork'."
compatibility: claude-code-only
allowed-tools:
- Read
- Write
- Edit
- Glob
- Grep
- Bash
---# Fork Discipline
Audit the core/client boundary in multi-client codebases. Every multi-client project should have a clean separation between shared platform code (core) and per-deployment code (client). This skill finds where that boundary is blurred and shows you how to fix it.
## The Principle
```
project/
src/ โ CORE: shared platform code. Never modified per client.
config/ โ DEFAULTS: base config, feature flags, sensible defaults.
clients/
client-name/ โ CLIENT: everything that varies per deployment.
config โ overrides merged over defaults
| Environment variables like `CLIENT_NAME` or `TENANT_ID` | Runtime multi-client |
| Only one deployment, no client dirs | Single-client (may be heading multi-client) |
If single-client: check if the project CLAUDE.md or codebase suggests it will become multi-client. If so, audit for readiness. If genuinely single-client forever, this skill isn't needed.
### Step 2: Map the Boundary
Build a boundary map by scanning the codebase:
```
CORE (shared by all clients):
src/server/ โ API routes, middleware, auth
src/client/ โ React components, hooks, pages
src/db/schema.ts โ Shared database schema
migrations/0001-0050 โ Core migrations
CLIENT (per-deployment):
clients/acme/config.ts โ Client overrides
clients/acme/kb/ โ Knowledge base articles
clients/acme/seed.sql โ Seed data
migrations/0100+ โ Client schema extensions
BLURRED (needs attention):
src/server/routes/acme-custom.ts โ Client code in core!
src/config/defaults.ts line 47 โ Hardcoded client domain
```
### Step 3: Find Violations
Scan for these specific anti-patterns:
#### Client Names in Core Code
```bash
# Search for hardcoded client identifiers in shared code
**Severity**: High. Every hardcoded client check in core code means the next client requires modifying shared code.
#### Config Replacement Instead of Merge
Check if client configs replace entire files or merge over defaults:
```typescript
// BAD โ client config is a complete replacement
// clients/acme/config.ts
export default {
theme: { primary: '#1E40AF' },
features: { emailOutbox: true },
// Missing all other defaults โ they're lost
}
// GOOD โ client config is a delta merged over defaults
// clients/acme/config.ts
export default {
theme: { primary: '#1E40AF' }, // Only overrides what's different
}
// config/defaults.ts has everything else
```
Look for: client config files that are suspiciously large (close to the size of the defaults file), or client configs that define fields the defaults already handle.
**Severity**: Medium. Stale client configs miss new defaults and features.
#### Scattered Client Code
Check if client-specific code lives outside the client directory:
```bash
# Files with client names in their path but inside src/
Write a script to `.jez/scripts/fork-refactor.sh` that:
- Creates the client directory structure
- Moves identified files
- Updates import paths
- Generates the FORK.md
---
## The Right Time to Run This
| Client count | What to do |
|-------------|-----------|
| 1 | Don't refactor. Just document the boundary (FORK.md) so you know where it is. |
| 2 | Run the audit. Fix high-severity violations. Start the config merge pattern. |
| 3+ | Full refactor mode. The boundary must be clean โ you now have proof of what varies. |
**Rule 5 from the discipline**: Don't abstract until client #3. With 1 client you're guessing. With 2 you're pattern-matching. With 3+ you know what actually varies.
## Tips
- Run this before adding a new client, not after
- Config merge is the single highest-ROI refactor โ do it first
- Feature flags beat `if (client)` even with one client. *"This is mostly the same except..."* = feature flag, not fork.
- FORK.md is for the team, not just for Claude โ write it like a human will read it