agentleFS
martincjarvismartincjarvis/development-skills/skills/scoped-colocation/SKILL.md

scoped-colocation

Skill4 starsChanged 10 months agoMITView on GitHub

Use when organizing code structure, creating new features, or reviewing file placement to keep related code together by scope and reduce cognitive load.

The file

Show its rules and text

We split this skill into the rules it gives an agent

14 rules. About 0 are common, 14 are distinctive, and 0 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈14

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 0

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Place code in that feature's directory (not in shared/utils)

    line 34
  2. Distinctive:

    Verify directory structure reflects feature boundaries

    line 38
  3. Distinctive:

    Rule: Do not prematurely extract.

    line 126
  4. Distinctive:

    Place code in that feature's directory

    line 159
  5. Distinctive:

    Only extract if truly shared (3+ consumers)

    line 162
  6. Distinctive:

    Check if code is used by only one feature

    line 166
  7. Distinctive:

    If single-feature, move to that feature's directory

    line 167
  8. Distinctive:

    Verify tests are colocated

    line 168
  9. Distinctive:

    Check for orphaned files in wrong directories

    line 169
  10. Distinctive:

    Keep genuinely shared code in shared locations

    line 176
  11. Distinctive:

    Update imports and references

    line 177
  12. Distinctive:

    All mean: Consider if the code belongs in a feature directory instead.

    line 187
  13. Distinctive:

    Before declaring structure complete:

    line 270
  14. Distinctive:

    Use this checklist to audit existing codebases:

    line 432

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 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.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Scoped Colocation

Overview

Keep related code together by scope. Scoped colocation organizes files by feature or domain rather than technical layer, reducing navigation overhead and making the codebase self-documenting.

Principle: Code that changes together should live together. When you modify a feature, you should not need to navigate across multiple unrelated directories.

REQUIRED BACKGROUND: superpowers:verification-before-completion

When to Use

Always triggered for:

  • Creating new features or components
  • Reviewing or refactoring existing file structure
  • Discussing project organization patterns
  • Onboarding to an unfamiliar codebase
  • Adding tests, styles, or related assets to existing features

Core Workflow

  1. Identify the owning feature or domain for the code
  2. Place code in that feature's directory (not in shared/utils)
  3. Colocate tests with implementation in the same directory
  4. Colocate related assets (styles, types, fixtures) with the feature
  5. Extract to shared only when genuinely shared (3+ consumers)
  6. Verify directory structure reflects feature boundaries

Core Patterns

Pattern 1: Feature-Scoped Directories

Organize by feature/domain, not by technical concern:

# Anti-pattern: Technical layers
src/
  controllers/
    OrderController.cs
    CustomerController.cs
  services/
    OrderService.cs
    CustomerService.cs
  models/
    Order.cs
    Customer.cs

# Preferred: Feature-scoped
src/
  Orders/
    OrderController.cs
    OrderService.cs
    Order.cs
    OrderTests.cs
  Customers/
    CustomerController.cs
    CustomerService.cs
    Customer.cs
    CustomerTests.cs

Pattern 2: Test Colocation

Tests live next to the code they test:

# Anti-pattern: Separate test tree
src/
  Components/
    Button.tsx
tests/
  Components/
    Button.test.tsx

# Preferred: Colocated tests
src/
  Components/
    Button.tsx
    Button.test.tsx

Pattern 3: Asset Colocation

Related assets (styles, types, fixtures) stay with their component:

src/
  Features/
    Dashboard/
      Dashboard.tsx
      Dashboard.module.css
      Dashboard.types.ts
      Dashboard.test.tsx
      dashboard-fixtures.json

Pattern 4: Shared Code Extraction

Extract only when genuinely shared (used in 3+ places):

src/
  Features/
    Orders/
      ... (feature-specific code)
    Customers/
      ... (feature-specific code)
  Shared/
    Components/
      Button.tsx        # Used by Orders, Customers, Reports
    Utils/
      formatDate.ts     # Used across multiple features

Rule: Do not prematurely extract. Keep code in features until sharing becomes necessary.

Decision Framework

When to Colocate

  • Code is used by only one feature
  • Code changes when the feature changes
  • Understanding requires feature context
  • Tests and implementation evolve together

When to Extract to Shared

  • Code is used by 3 or more features
  • Code is stable and unlikely to change per-feature
  • Code represents a cross-cutting concern (auth, logging)
  • Code is a foundational utility (date formatting, validation)

Colocation Hierarchy

1. Same file (functions, types)
2. Same directory (component + test + styles)
3. Feature directory (all feature-related code)
4. Domain directory (related features grouped)
5. Shared (cross-cutting, stable, reusable)

Required Actions

When Creating New Code

  1. Identify the owning feature or domain
  2. Place code in that feature's directory
  3. Colocate tests with implementation
  4. Colocate related assets (styles, types, fixtures)
  5. Only extract if truly shared (3+ consumers)

When Reviewing Code Placement

  1. Check if code is used by only one feature
  2. If single-feature, move to that feature's directory
  3. Verify tests are colocated
  4. Check for orphaned files in wrong directories

When Refactoring Structure

  1. Identify features/domains in the codebase
  2. Group related files by feature
  3. Move single-feature code out of "shared" directories
  4. Keep genuinely shared code in shared locations
  5. Update imports and references

Red Flags - STOP

  • Creating a new utils/ or helpers/ file for single-feature code
  • Placing tests in a separate __tests__/ tree far from implementation
  • Adding feature-specific code to a "common" or "shared" directory
  • Organizing primarily by file type (all controllers together, all models together)
  • Premature extraction ("might need this elsewhere")

All mean: Consider if the code belongs in a feature directory instead.

Benefits

BenefitDescription
Reduced navigationRelated files in same directory
Self-documentingDirectory structure reveals feature boundaries
Easier deletionRemove feature by deleting one directory
Clear ownershipObvious which team owns which code
Simpler importsShorter, more intuitive import paths
Better encapsulationFeature internals hidden from other features

Language-Specific Examples

React/TypeScript

src/
  features/
    auth/
      LoginForm.tsx
      LoginForm.test.tsx
      LoginForm.module.css
      useAuth.ts
      useAuth.test.ts
      auth.types.ts
    dashboard/
      Dashboard.tsx
      Dashboard.test.tsx
      DashboardWidget.tsx
      useDashboardData.ts

.NET (C#)

src/
  Features/
    Orders/
      CreateOrderCommand.cs
      CreateOrderCommandHandler.cs
      CreateOrderCommandTests.cs
      OrderRepository.cs
      OrderDto.cs
    Customers/
      GetCustomerQuery.cs
      GetCustomerQueryHandler.cs
      CustomerService.cs

Python

src/
  features/
    orders/
      __init__.py
      routes.py
      service.py
      models.py
      test_orders.py
    customers/
      __init__.py
      routes.py
      service.py
      models.py
      test_customers.py

Exceptions

Certain code legitimately belongs in shared/common locations:

  • Framework configuration (startup, middleware setup)
  • Cross-cutting infrastructure (logging, caching, auth middleware)
  • Domain primitives used across all features (Money, DateRange)
  • Build/deployment configuration (CI/CD, Docker)

These exceptions should be documented in the project's architecture documentation.

Verification Checklist

Before declaring structure complete:

  • Feature code lives in feature directories
  • Tests are colocated with implementation
  • Related assets are in same directory
  • Shared code is genuinely shared (3+ consumers)
  • No premature extraction to utils/helpers
  • Directory structure reflects feature boundaries

Sample Directory Layouts

Full-Stack Application (React + Node.js)

project/
├── src/
│   ├── features/
│   │   ├── auth/
│   │   │   ├── components/
│   │   │   │   ├── LoginForm.tsx
│   │   │   │   ├── LoginForm.test.tsx
│   │   │   │   └── LoginForm.module.css
│   │   │   ├── hooks/
│   │   │   │   ├── useAuth.ts
│   │   │   │   └── useAuth.test.ts
│   │   │   ├── api/
│   │   │   │   ├── authApi.ts
│   │   │   │   └── authApi.test.ts
│   │   │   └── index.ts           # Public exports
│   │   │
│   │   ├── orders/
│   │   │   ├── components/
│   │   │   │   ├── OrderList.tsx
│   │   │   │   ├── OrderList.test.tsx
│   │   │   │   ├── OrderDetail.tsx
│   │   │   │   └── OrderDetail.test.tsx
│   │   │   ├── hooks/
│   │   │   │   ├── useOrders.ts
│   │   │   │   └── useOrders.test.ts
│   │   │   ├── types/
│   │   │   │   └── order.types.ts
│   │   │   └── index.ts
│   │   │
│   │   └── dashboard/
│   │       ├── Dashboard.tsx
│   │       ├── Dashboard.test.tsx
│   │       └── widgets/
│   │           ├── SalesWidget.tsx
│   │           └── SalesWidget.test.tsx
│   │
│   ├── shared/                     # Only truly shared (3+ consumers)
│   │   ├── components/
│   │   │   ├── Button.tsx
│   │   │   ├── Button.test.tsx
│   │   │   └── Modal.tsx
│   │   └── utils/
│   │       ├── formatDate.ts
│   │       └── formatDate.test.ts
│   │
│   └── infrastructure/             # Framework/cross-cutting
│       ├── http/
│       │   └── apiClient.ts
│       └── store/
│           └── configureStore.ts
│
└── package.json

.NET Clean Architecture

src/
├── Domain/                         # Core business logic
│   ├── Orders/
│   │   ├── Order.cs
│   │   ├── OrderItem.cs
│   │   └── IOrderRepository.cs
│   └── Customers/
│       ├── Customer.cs
│       └── ICustomerRepository.cs
│
├── Application/                    # Use cases
│   ├── Orders/
│   │   ├── Commands/
│   │   │   ├── CreateOrder/
│   │   │   │   ├── CreateOrderCommand.cs
│   │   │   │   ├── CreateOrderHandler.cs
│   │   │   │   └── CreateOrderValidator.cs
│   │   │   └── CancelOrder/
│   │   │       ├── CancelOrderCommand.cs
│   │   │       └── CancelOrderHandler.cs
│   │   └── Queries/
│   │       └── GetOrder/
│   │           ├── GetOrderQuery.cs
│   │           └── GetOrderHandler.cs
│   └── Common/
│       └── Behaviors/              # Cross-cutting (logging, validation)
│
├── Infrastructure/                 # External concerns
│   ├── Persistence/
│   │   ├── Orders/
│   │   │   └── OrderRepository.cs
│   │   └── AppDbContext.cs
│   └── ExternalServices/
│
└── WebApi/                         # Presentation
    ├── Controllers/
    │   ├── OrdersController.cs
    │   └── CustomersController.cs
    └── Program.cs

tests/
├── Domain.Tests/
│   └── Orders/
│       └── OrderTests.cs
├── Application.Tests/
│   └── Orders/
│       └── CreateOrderHandlerTests.cs
└── WebApi.Tests/
    └── Orders/
        └── OrdersControllerTests.cs

Python FastAPI

src/
├── features/
│   ├── auth/
│   │   ├── __init__.py
│   │   ├── router.py
│   │   ├── service.py
│   │   ├── models.py
│   │   ├── schemas.py
│   │   └── test_auth.py
│   │
│   ├── orders/
│   │   ├── __init__.py
│   │   ├── router.py
│   │   ├── service.py
│   │   ├── models.py
│   │   ├── schemas.py
│   │   └── test_orders.py
│   │
│   └── customers/
│       ├── __init__.py
│       ├── router.py
│       └── test_customers.py
│
├── shared/
│   ├── __init__.py
│   ├── database.py
│   └── utils/
│       ├── __init__.py
│       └── date_utils.py
│
├── main.py
└── conftest.py                     # Shared test fixtures

Colocation Audit Checklist

Use this checklist to audit existing codebases:

Phase 1: Discovery

  • List all top-level directories
  • Identify if organized by technical layer or feature
  • Count features/domains in the codebase
  • Identify test location pattern

Phase 2: Analysis

For each feature identified:

FeatureCode LocationTest LocationColocated?Action
Authsrc/features/authtests/auth✓ YesNone
Orderssrc/services/tests/services/✗ NoMove
Utilssrc/utils/tests/utils/⚠ CheckReview usage

Phase 3: Shared Code Audit

For each file in shared/, common/, utils/:

FileUsed ByCountAction
formatDate.tsauth, orders, reports3Keep in shared
orderHelpers.tsorders only1Move to orders/
constants.tsauth, orders2Keep but watch

Phase 4: Refactoring Priority

Based on analysis, prioritize:

  1. High: Single-feature code in shared directories
  2. Medium: Tests not colocated with implementation
  3. Low: Assets (styles, fixtures) not colocated

Audit Script

#!/bin/bash
# colocation-audit.sh

echo "=== Colocation Audit ==="
echo ""

# Check for common anti-patterns
echo "## Anti-pattern Detection"

# Separate test directories
if [ -d "tests" ] || [ -d "__tests__" ]; then
  TEST_COUNT=$(find . -name "*.test.*" -o -name "*_test.*" | wc -l)
  COLOCATED=$(find src -name "*.test.*" -o -name "*_test.*" 2>/dev/null | wc -l)
  echo "Total tests: $TEST_COUNT"
  echo "Colocated tests: $COLOCATED"
  if [ "$COLOCATED" -lt "$TEST_COUNT" ]; then
    echo "⚠ Some tests not colocated with source"
  fi
fi

# Check utils/helpers directories
for dir in utils helpers common; do
  if [ -d "src/$dir" ]; then
    FILE_COUNT=$(find "src/$dir" -type f -name "*.ts" -o -name "*.js" -o -name "*.py" | wc -l)
    echo "⚠ Found src/$dir with $FILE_COUNT files - review for single-feature code"
  fi
done

# Check for feature directories
echo ""
echo "## Feature Directory Detection"
if [ -d "src/features" ]; then
  echo "✓ Feature-based structure detected"
  ls -d src/features/*/ 2>/dev/null | while read dir; do
    FEATURE=$(basename "$dir")
    TEST_FILES=$(find "$dir" -name "*.test.*" -o -name "*_test.*" | wc -l)
    echo "  $FEATURE: $TEST_FILES colocated tests"
  done
else
  echo "⚠ No features/ directory - consider restructuring"
fi

echo ""
echo "=== Audit Complete ==="

Evidence Template

## Colocation Audit Results

**Repository**: [repo-name]
**Date**: YYYY-MM-DD
**Auditor**: [name]

### Current Structure

[Describe current organization pattern]

### Findings

| Category             | Status | Details                   |
| -------------------- | ------ | ------------------------- |
| Feature directories  | ✓/✗    | [describe]                |
| Test colocation      | ✓/✗    | [X]% colocated            |
| Shared code validity | ✓/✗    | [X] files, [Y] single-use |

### Recommended Actions

1. [ ] Move [X] to feature directory [Y]
2. [ ] Colocate tests for [feature]
3. [ ] Review shared/utils for single-use code

### Verification

After refactoring:

- [ ] All tests pass
- [ ] Import paths updated
- [ ] No orphaned files

Download now (ZIP)

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
What did you use it for? e.g. Reviewing pull requests in a Rails app

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.