clean-branch
Skill4 starsChanged 2 months agoMITView on GitHub
Update the `clean` branch by rebasing from `dev` and stripping all domain-specific code. Use when `dev` has architectural changes that should be reflected in the generic boilerplate. Use this skill to maintain the clean boilerplate branch.
- Deletes or force-pushes
We split this skill into the rules it gives an agent
35 rules. About 0 are common, 17 are distinctive, and 18 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈17
Distinctive · estimate
This author's own choices. Worth a look.
18
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 76
If rebase has conflicts, resolve them favoring the clean side for stripped files and dev side for infrastructure files.
- Distinctive: line 80
Run discovery to find what needs stripping:
- Distinctive: line 114
Remove import for deleted context routers
- Very specific: line 115
Remove their entries from the ROUTERS map and from CONTEXTS (the satisfies Record<ContextModule, Router> check fails until both agree — …
- Very specific: line 116
Keep only the template contexts: SharedRouter, AuthRouter, BillingRouter, OwnerRouter, QuotaRouter, NotificationsRouter, UiRouter (shared, …
- Very specific: line 121
Remove all import statements from deleted contexts (usecases, repositories)
- Very specific: line 122
Remove all container.registerSingleton() calls for deleted repos
- Very specific: line 123
Update AllUseCases type and allUseCases object to only include auth + ui use cases
- Distinctive: line 126
Remove exports for deleted context schemas
- Very specific: line 127
Keep only: export * from './authentication' and export * from './ui'
- Distinctive: line 130
Remove exports for domain-specific enums
- Very specific: line 131
Keep only generic enums: BrazilianState, Country, Language, NotificationLevel, RoleType
- Distinctive: line 134
Remove all event exports (events are domain-specific)
- Distinctive: line 138
Remove imports from deleted context error types
- Distinctive: line 139
Remove error entries for deleted contexts
- Distinctive: line 140
Keep: shared, auth, UI, BetterAuth error entries
- Very specific: line 154
Update packages/api/typescript/src/ui/controllers/index.ts to only export generic controllers (notifications, onboarding, user details)
- Very specific: line 157
Remove enums that only exist for domain UI (e.g., PatientListTab, ServiceStatus, AuditLogType)
- Very specific: line 167
Remove domain-specific fields (e.g., type property for user categories)
- Very specific: line 168
Default step should be WELCOME
- Distinctive: line 172
Delete all domain-specific route directories:
- Distinctive: line 199
Remove all SDK imports, replace with static data
- Distinctive: line 203
Remove domain-specific navigation items, mode selectors, context selectors
- Distinctive: line 208
Remove SDK imports for notifications/user data
- Very specific: line 210
Create local types.ts for Notification interface if needed
- Distinctive: line 214
Remove domain-specific form fields (e.g., document, language, mode selector)
- Very specific: line 229
Remove domain-specific session fields (e.g., mode)
- Distinctive: line 230
Keep only generic user fields
- Very specific: line 242
Ensure all references use @monorepo namespace (not the project-specific name):
- Very specific: line 249
If found, replace with @monorepo equivalents:
- Very specific: line 264
Verify the generated SQL only contains authentication and ui schema tables.
- Distinctive: line 273
Ensure README.md is generic boilerplate (not domain-specific).
- Distinctive: line 299
Search for any remaining domain-specific references:
- Distinctive: line 313
Commit in logical batches or as a single squashed commit:
- Very specific: line 340
After deleting frontend routes, always run cd packages/app && bun tsr generate before committing.
≈ “Common” is an estimate: at least 1 in 5 of the 308,232 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Update Clean Branch
Synchronizes the clean branch with dev by rebasing and then stripping all domain-specific code, leaving a generic fullstack TypeScript boilerplate.
Why This Exists
The clean branch serves as a reusable starting point for new projects. Whenever dev gains architectural improvements (new patterns, infrastructure, tooling), clean should inherit those improvements without any domain-specific code.
When to Use
devhas new architectural changes (infrastructure, tooling, shared patterns) thatcleanshould inherit- New bounded contexts were added to
devthat need to be stripped fromclean - New frontend routes/pages were added that are domain-specific
- Shared utilities or enums were added that are domain-specific
When NOT to Use
- Changes on
devare purely domain-specific with no architectural value - The
cleanbranch doesn't exist yet (create it first with a full initial strip) - You only need to fix a bug on
clean(just fix it directly)
Prerequisites
- The
cleanbranch exists and was previously stripped - You understand which bounded contexts are domain-specific vs. generic
- Working directory is clean (no uncommitted changes)
What Gets Kept vs. Stripped
Always Keep (Generic Infrastructure)
| Category | What |
| Backend contexts | shared, auth, ui |
| Shared enums | Country, Language, BrazilianState, NotificationLevel, RoleType |
| Shared infra | DI container, error handling, OpenAPI, mediator, services |
| Auth | BetterAuth setup, session, sign-in/sign-up controllers |
| UI context | Onboarding (generic), user details, notifications |
| Frontend | Landing page (generic), sign-in, sign-up, reset-password, dashboard (generic) |
| Components | Navbar (Dashboard only), Header (breadcrumbs + notifications), all primitives |
| Skills & Agents | All .claude/skills/ and .claude/agents/ (with @monorepo namespace) |
| Docs | BACKEND.md, FRONTEND.md, COMPONENTS.md |
Always Strip (Domain-Specific)
| Category | What |
| Backend contexts | Any context beyond shared, auth, ui (e.g., clinic, doctor, patient, service, agent) |
| Domain enums | Enums tied to business logic (e.g., AppointmentStatus, MemberType, ExternalPlatform) |
| Domain schemas | Drizzle schema files beyond authentication.ts and ui.ts |
| Domain events | All event files (events are domain-specific by nature) |
| Frontend routes | Any route beyond /dashboard, /sign-in, /sign-up, /reset-password, / (landing) |
| Domain components | Dashboard sections beyond generic overview, domain-specific dialogs/forms |
| Project docs | SYSTEM.md, PRD.md, .plans/, docs/reviews/, prompts/ |
Process
Step 0: Preparation
# Ensure clean working directory
git status
# Switch to clean branch
git checkout clean
# Rebase onto dev
git rebase devIf rebase has conflicts, resolve them favoring the clean side for stripped files and dev side for infrastructure files. If too many conflicts, consider git checkout clean && git reset --hard dev and re-stripping from scratch.
Step 1: Identify What's New on dev
Run discovery to find what needs stripping:
# List all backend contexts (directories under packages/api/typescript/src/ with index.ts)
ls -d packages/api/typescript/src/*/
# List all Drizzle schema files
ls packages/api/typescript/src/shared/db/drizzle/schema/
# List all frontend route directories
ls -d packages/app/src/routes/*/
ls -d packages/app/src/routes/\(app\)/*/
# List all shared enums
ls packages/api/typescript/src/shared/enums/
# List all shared events
ls packages/api/typescript/src/shared/events/
# Search for domain-specific routers in the composition root
grep "import.*Router.*from" packages/api/typescript/src/routers.tsCompare against the "Always Keep" list above. Everything else is a candidate for stripping.
Step 2: Strip Backend Contexts
For each domain-specific context directory:
rm -rf packages/api/typescript/src/<context>/Then update packages/api/typescript/src/routers.ts and the CONTEXTS manifest (packages/api/typescript/src/shared/contexts.ts):
- Remove import for deleted context routers
- Remove their entries from the
ROUTERSmap and fromCONTEXTS(thesatisfies Record<ContextModule, Router>check fails until both agree — same forCONTEXT_REGISTRIESinshared/registry.ts) - Keep only the template contexts:
SharedRouter,AuthRouter,BillingRouter,OwnerRouter,QuotaRouter,NotificationsRouter,UiRouter(shared, auth, billing, owner, quota, notifications, ui)
Step 3: Clean Shared References
packages/api/typescript/src/shared/index.ts (DI container):
- Remove all
importstatements from deleted contexts (usecases, repositories) - Remove all
container.registerSingleton()calls for deleted repos - Update
AllUseCasestype andallUseCasesobject to only include auth + ui use cases
packages/api/typescript/src/shared/db/drizzle/schema/index.ts:
- Remove exports for deleted context schemas
- Keep only:
export * from './authentication'andexport * from './ui'
packages/api/typescript/src/shared/enums/index.ts:
- Remove exports for domain-specific enums
- Keep only generic enums:
BrazilianState,Country,Language,NotificationLevel,RoleType
packages/api/typescript/src/shared/events/index.ts:
- Remove all event exports (events are domain-specific)
- Replace with:
// Domain events will be added here as contexts are created
packages/api/typescript/src/shared/utils/GlobalErrorMapper.ts:
- Remove imports from deleted context error types
- Remove error entries for deleted contexts
- Keep: shared, auth, UI, BetterAuth error entries
Delete domain-specific shared files:
packages/api/typescript/src/shared/db/drizzle/schema/<context>.tsfor each deleted contextpackages/api/typescript/src/shared/enums/<DomainEnum>.tsfor domain enumspackages/api/typescript/src/shared/events/<DomainEvent>.tsfor all eventspackages/api/typescript/src/shared/schemas/<domain>.tsfor domain schemas
Step 4: Clean UI Context
The ui context often accumulates domain-specific BFF controllers and enums.
Delete domain-specific UI controllers:
- Any controller directory under
packages/api/typescript/src/ui/controllers/that serves domain pages (e.g.,dashboard/,patients/,services/) - Update
packages/api/typescript/src/ui/controllers/index.tsto only export generic controllers (notifications, onboarding, user details)
Delete domain-specific UI enums:
- Remove enums that only exist for domain UI (e.g.,
PatientListTab,ServiceStatus,AuditLogType) - Simplify
OnboardingStepto:{ WELCOME, COMPLETED }
Simplify UI use cases:
CompleteOnboarding: Remove domain entity creation (e.g., doctor/clinic), just mark as completedGetUserDetails: Remove domain queries, return basic user info onlySaveOnboardingState: Remove domain-specific schema fieldsGetOnboarding: Remove domain-specific type fields
Simplify Onboarding entity:
- Remove domain-specific fields (e.g.,
typeproperty for user categories) - Default step should be
WELCOME
Step 5: Strip Frontend Routes
Delete all domain-specific route directories:
# Delete domain-specific app routes
rm -rf packages/app/src/routes/\(app\)/<domain-route>/
# Delete domain-specific standalone routes
rm -rf packages/app/src/routes/<domain-route>/
# Delete domain-specific dashboard sections
rm -rf "packages/app/src/routes/(app)/dashboard/-components/<DomainSection>/"Keep only:
packages/app/src/routes/(app)/dashboard/(with generic OverviewSection only)packages/app/src/routes/(index)/(landing page)packages/app/src/routes/sign-in/packages/app/src/routes/sign-up/packages/app/src/routes/reset-password/packages/app/src/routes/(app)/route.tsx(layout)
Step 6: Simplify Frontend Components
Dashboard (packages/app/src/routes/(app)/dashboard/):
- Rewrite
index.tsxto only render<OverviewSection /> - Rewrite
-components/index.tsxto only exportOverviewSection+OverviewSectionSkeleton - Simplify
OverviewSectionto show a welcome message and generic placeholder stats - Remove all SDK imports, replace with static data
Navbar (packages/app/src/components/Navbar/index.tsx):
- Single
NAVIGATION_ITEMSwith only Dashboard - Remove domain-specific navigation items, mode selectors, context selectors
- Remove SDK imports
- Generic logo ("App" with
IconLayoutDashboard)
Header (packages/app/src/components/Header/):
- Remove SDK imports for notifications/user data
- Replace with mock data +
// TODO: Replace with real data hooks when SDK is available - Create local
types.tsforNotificationinterface if needed
Auth pages (sign-in, sign-up, reset-password):
- Replace SDK schema imports with inline zod schemas
- Remove domain-specific form fields (e.g., document, language, mode selector)
- Generic sidebar content (no domain branding)
- Navigation should go to
/or/dashboard, not domain-specific routes
Landing page (packages/app/src/routes/(index)/index.tsx):
- Replace all domain content with generic SaaS boilerplate in English
- Placeholder features, stats, testimonials
- Generic "App" branding
Frontend lib files:
packages/app/src/lib/labels.ts: Empty withexport {}packages/app/src/lib/consts.ts: Empty withexport {}packages/app/src/lib/errors.ts: Remove SDK error imports, keep generic error utilities
Vite env types (packages/app/src/vite-env.d.ts):
- Remove domain-specific session fields (e.g.,
mode) - Keep only generic user fields
Step 7: Regenerate Route Tree
cd packages/app && bun tsr generateThis removes deleted routes from routeTree.gen.ts.
Step 8: Namespace Check
Ensure all references use @monorepo namespace (not the project-specific name):
# Search for project-specific namespace
grep -ri "<project-name>" --include="*.ts" --include="*.tsx" --include="*.json" --include="*.md" -l .If found, replace with @monorepo equivalents:
- Package names:
@monorepo/api,@monorepo/app,@monorepo/sdk - SDK imports:
@monorepo/sdk/app,@monorepo/sdk/http,@monorepo/sdk/api - Skills/agents:
@monorepo/sdkreferences
Step 9: Fresh Database Migration
# Delete old migrations
rm -rf packages/api/typescript/src/shared/db/drizzle/migrations
# Generate fresh migration from current clean schema
bun migrate:createVerify the generated SQL only contains authentication and ui schema tables.
Step 10: Clean Project Docs
rm -f SYSTEM.md PRD.md
rm -rf docs/reviews .plans promptsEnsure README.md is generic boilerplate (not domain-specific). Ensure CLAUDE.md uses "Monorepo Boilerplate" title.
Step 11: Verify Build
# Type check
bun tsc
# Lint
bun lint
# Tests
bun test
# Full build (optional but recommended)
bun buildFix any errors. Common issues:
- Empty files that aren't modules (add
export {}) - Unused imports from deleted code
- Missing error entries in GlobalErrorMapper
- Route tree referencing deleted routes
Step 12: Final Sweep
Search for any remaining domain-specific references:
# Search for domain terms in source files
grep -ri "clinic\|patient\|doctor\|appointment\|specialty" --include="*.ts" --include="*.tsx" -l packages/app/src/ packages/api/typescript/src/
# Search for project-specific name
grep -ri "<project-name>" --include="*.ts" --include="*.tsx" --include="*.json" --include="*.md" -l .Fix any remaining references. Then commit.
Step 13: Commit
Commit in logical batches or as a single squashed commit:
git add -A
git commit -m "chore: update clean branch from dev - strip domain-specific code"Critical Rules
Always Run Type Check Before Committing
The pre-commit hook runs bun tsc, bun test, and full build. Deleting contexts without fixing dangling imports will fail the commit. Fix ALL references atomically — don't try to commit partial deletions.
Backend DI Container Is the Hub
packages/api/typescript/src/shared/index.ts registers ALL repositories and use cases. When deleting a context, you MUST remove its registrations here or the build will fail.
GlobalErrorMapper Must Be Exhaustive
The GlobalErrorMapper Record type requires entries for ALL error types across all remaining contexts. If you remove an error type from a context but it's still referenced by another context's error union, you'll get a type error. Either remove the reference or keep the entry.
BetterAuth May Have Deep Coupling
Auth hooks (e.g., afterSignInHook, customSession) may reference domain-specific types/repos. Review packages/api/typescript/src/auth/services/Authentication/BetterAuth.ts carefully and remove domain-specific plugins/hooks.
Route Tree Must Be Regenerated
After deleting frontend routes, always run cd packages/app && bun tsr generate before committing. The generated routeTree.gen.ts will reference deleted routes and cause build failures.
Events Are Always Domain-Specific
Domain events should be completely removed. The shared events barrel (packages/api/typescript/src/shared/events/index.ts) should be empty. Event handlers go away with their contexts.
UI Context Accumulates Domain Code
Even though ui is a kept context, it often has domain-specific BFF controllers, enums, and use case logic that reference deleted contexts. Always audit packages/api/typescript/src/ui/ thoroughly.
Checklist
- Rebased
cleanonto latestdev - Identified all new domain-specific contexts since last sync
- Deleted domain-specific backend context directories
- Cleaned
packages/api/typescript/src/routers.ts(ROUTERSmap) + theCONTEXTSmanifest - Cleaned
packages/api/typescript/src/shared/index.tsDI registrations - Cleaned shared schemas, enums, events, errors
- Cleaned GlobalErrorMapper
- Cleaned UI context (controllers, enums, use cases)
- Deleted domain-specific frontend routes
- Simplified dashboard to generic overview
- Simplified navbar (Dashboard only, no mode/context selectors)
- Simplified header (mock data, no SDK imports)
- Simplified auth pages (inline schemas, no domain fields)
- Genericized landing page
- Cleaned frontend lib (labels, consts, errors)
- Cleaned vite-env.d.ts (no domain session fields)
- Regenerated route tree (
cd packages/app && bun tsr generate) - Verified namespace is
@monorepoeverywhere - Generated fresh database migration
- Cleaned project docs (no SYSTEM.md, PRD.md, plans, reviews)
bun tscpassesbun testpassesbun lintpasses- No remaining domain-specific terms in source files
- Committed changes
References
docs/BACKEND.md- Backend conventionsdocs/FRONTEND.md- Frontend conventionspackages/api/typescript/src/shared/index.ts- DI container (central hub for registrations)packages/api/typescript/src/shared/utils/GlobalErrorMapper.ts- Error mapping (must be exhaustive)packages/api/typescript/src/shared/db/drizzle/schema/index.ts- Schema barrel exports
In this repository45 other files it gives its agents.
- CLAUDE.mdCLAUDE.md
- agentSkill
- bounded-contextSkill
- commitSkill
- componentSkill
- controllerSkill
- db-modellingSkill
- ddd-modelingSkill
- ddd-specSkill
- design-systemSkill
- desktop-shellSkill
- e2eSkill
- entitySkill
- enumSkill
- errorsSkill
- eventSkill
- formSkill
- grill-with-docsSkill
- handlerSkill
- handoffSkill
- middlewareSkill
- migrateSkill
- prdSkill
- primitiveSkill
- projectionSkill
- projectorSkill
- querySkill
- repositorySkill
- reviewSkill
- routeSkill
- saas-researchSkill
- schedulerSkill
- schemaSkill
- sdkSkill
- serviceSkill
- spec-reviewSkill
- storeSkill
- storybookSkill
- task-breakdownSkill
- testSkill
- trace-analysisSkill
- ui-compositionSkill
- usecaseSkill
- user-storiesSkill
- value-objectSkill
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

