Skip to content
Agentmart
Submit a tool

design-principles

Use when writing production code — enforces dependency inversion and testable design through checkpoint questions before writing function signatures and…

Skill by ovargas

IndexedMIT★ 14
Write a review

Install

Works with Claude Code, Claude apps, Codex, Cursor, Gemini CLI, GitHub Copilot, VS Code, OpenCode, Goose, Windsurf. Read the repository before you give any tool access to your data.

npx agentmarket install skill/ovargas-design-principles

Asks which of your tools to add it to (Claude Code, Codex, Cursor, VS Code, Windsurf, Gemini CLI, Claude Desktop) and shows the change first. See https://agentmart.dev/cli.

Get the weekly diff

The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.

We use your email only for this newsletter. Privacy

About

Use when writing production code — enforces dependency inversion and testable design through checkpoint questions before writing function signatures and constructors

Use cases: design, writing

No reviews yet. Installed it? Reviews come from verified installers only. How reviews work

Permissions

What this skill can do and what it asks for, from its SKILL.md and code. Checked Oct 25, 2026.

Tools
No tools found
Secrets
None asked for
Install scripts
None found

Network hosts it talks to 1

  • codeload.github.com · found in install command

Files it touches

  • ~/.claude/skills/design-principles

What's inside

Skill name
design-principles
Description
Use when writing production code — enforces dependency inversion and testable design through checkpoint questions before writing function signatures and constructors
License
MIT
Instructions
163 lines in SKILL.md · view on GitHub

Files (1)

  • SKILL.md

SKILL.md (first lines)

# Design Principles

## Mode Selection

Read `stack.md` and check the `design:` field. If the field is missing, default to **recommended**.

| `design:` value | Behavior |
|-----------------|----------|
| `strict` | Every function boundary must pass the checkpoint. Rewrite if it fails. |
| `recommended` | Check at key boundaries (constructors, service functions, handlers). Flag skips. |
| `off` | No enforcement. Skip the rest of this skill. |

**If `design: off`** — stop reading.

## Core Principle

**Accept what you need. Don't create what you use.**

A function that creates its own collaborators is a function that can't be tested in isolation. A function that receives them can be tested with any substitute — mock, stub, fake, or the real thing.

This is Dependency Inversion: depend on the behavior you need, not the thing that provides it.

## The Checkpoint

Before writing a function signature, constructor, or method — pause and ask:

### 1. "What does this function need from the outside world?"

List the external collaborators: database access, HTTP clients, file system, other services, time, randomness.

If the answer is "nothing" — no checkpoint needed. Pure logic is already testable.

If the answer is "something" — continue to question 2.

### 2. "Am I accepting it or creating it?"

<Good>
```
// Accepts its dependency — caller decides what to pass
function createUser(repo: UserRepository, data: NewUser): Promise<User>
```
</Good>

<Bad>
```
// Creates its own dependency — hardwired to one implementation
function createUser(data: NewUser): Promise<User> {
  const repo = new PostgresUserRepository(getConnectionPool())
  // ...
}
```
</Bad>

If you're about to write `new`, `import` a concrete client, or call a constructor for something that does I/O — you're creating, not accepting. Restructure.

### 3. "Am I depending on a behavior or an implementation?"

The parameter type should describe **what you need**, not **who provides it**.

<Good>
```
// Depends on behavior — any implementation works
interface UserRepository {
  findById(id: string): Promise<User | null>
  save(user: User): Promise<void>
}
```
</Good>

<Bad>
```
// Depends on implementation — locked to Postgres
function createUser(repo: PostgresUserRepository, data: NewUser)
```
</Bad>

Not every language has explicit interfaces. The principle still applies:
- **TypeScript/Java/C#:** Use interfaces or abstract types at boundaries
- **Python:** Use protocols (typing.Protocol) or ABC at boundaries
- **Go:** Interfaces are implicit — accept the interface, return the struct
- **Ruby/JS:** Duck typing — document the expected shape, accept any object that quacks

The key: your function's contract is with a **shape**, not a **name**.

## When This Matters Most

Not every function needs this checkpoint. Focus on **boundaries** — where your code meets the outside world:

| Boundary | Checkpoint applies | Why |
|----------|-------------------|-----|
| Service/use-case functions | **Yes** | These orchestrate — they need collaborators |
| Constructors / factory functions | **Yes** | This is where dependencies get wired |
| Route handlers / controllers | **Yes** | These connect HTTP to business logic |
| Pure business logic | No | No external dependencies to invert |
| Simple utilities | No | `formatDate()` doesn't need dependency injection |
| Glue code / composition root | No | This is *where* you wire concretes — that's its job |

## The Composition Root

Every application has one place where concrete implementations are wired together. This is the **composition root** — the entry point, the main function, the DI container setup.

Concrete instantiation belongs here, not in business logic:

```
// composition root — the ONE place that knows about concretes
const repo = new PostgresUserRepository(pool)
const emailer = new SmtpEmailService(config)
const handler = new CreateUserHandler(repo, emailer)

app.post('/api/users', (req, res) => handler.handle(req, res))
```

If you find yourself writing `new ConcreteService()` outside the composition root, pause. You're wiring in the wrong place.

## Relationship with TDD

This skill and TDD are complementary:

- **TDD asks:** "What test proves this works?"

From ovargas/virtual-team, MIT.

More from ovargas/virtual-team

Signals

Stars
14
Forks
1
Open issues
0
Last commit (this folder)
May 12, 2026 (5 months ago)
Last release
Oct 8, 2026 (20 days ago)

From GitHub (fetched Oct 24, 2026).

Details

License
MIT
First seen
Oct 24, 2026
Last checked
Oct 24, 2026

More from ovargas

Cite this page

design-principles skill. Agent Mart. https://agentmart.dev/skills/ovargas-design-principles (last updated 2026-10-24)