CtrlK
BlogDocsLog inGet started
Tessl Logo

evilissimo/software-design

Use before implementing or refactoring software. Contains two skills: (1) Modular Software Design — for designing module boundaries, APIs, layers, abstractions, services, repositories, adapters, or architecture, helping reduce total system complexity by creating deep modules, hiding implementation knowledge, avoiding leakage and pass-through APIs, comparing alternative designs, documenting interfaces before coding, and critiquing existing architecture; and (2) Software Testing — for writing unit tests, integration tests, or end-to-end tests, creating mocks/stubs/fakes, designing a testing strategy, doing TDD, reviewing test quality, fixing flaky tests, or refactoring test suites, generating risk-focused test plans, picking appropriate test levels, choosing between mocks/fakes/real dependencies, and applying Arrange-Act-Assert patterns with concrete examples.

88

Quality

88%

Does it follow best practices?

Impact

No eval scenarios have been run

SecuritybySnyk

Passed

No known issues

Overview
Quality
Evals
Security
Files

SKILL.mdskills/modular-software-design-skill/

name:
modular-software-design
description:
Use before implementing or refactoring software when the task requires designing module boundaries, APIs, layers, abstractions, services, repositories, adapters, or architecture. Helps coding agents reduce total system complexity by creating deep modules, hiding implementation knowledge, avoiding leakage and pass-through APIs, comparing alternative designs, documenting interfaces before coding, and critiquing existing architecture.

Modular Software Design

Use this skill before coding when a task involves new modules, changed boundaries, public APIs, services, repositories, domain objects, adapters, layers, or architecture refactoring.

Goal: reduce total system complexity. Optimize for lower cognitive load, fewer unknown unknowns, localized change, and simpler caller experience. Do not optimize for more classes, fewer lines, architecture-pattern compliance, or local cleverness.

Required Output Before Coding

For non-trivial changes, produce a compact design brief before implementation. Use templates/design-brief.md when useful.

Task:
Complexity goal:
Candidate modules and interfaces:
Hidden implementation knowledge:
Alternative designs considered:
Chosen design and rationale:
Leakage/pass-through risks:
Layering plan:
Tests and interface documentation:

Do not proceed directly to implementation unless the change is purely mechanical or the user explicitly asks to skip design.

Core Concepts to Apply

A deep module provides high functionality behind a small, simple interface. Its implementation may be complex, but callers do not need to know its internal decisions, sequencing, data representation, vendor behavior, persistence, validation, retries, or special cases.

A module is suspicious when its interface is nearly as complex as its implementation, mainly forwards calls, mirrors another layer, exposes raw implementation shapes, or forces callers to coordinate internal steps.

Use the detailed rules in:

Workflow

  1. State the complexity goal. Identify the change amplification, cognitive load, hidden coupling, or unknown unknowns the design should reduce.
  2. Identify concepts, not steps. Avoid temporal decomposition such as parser/validator/processor/responder unless those are true abstractions. Prefer concepts that own decisions or invariants.
  3. Draft at least two designs. Compare module depth, public surface area, leakage, pass-through code, layer fit, change impact, and caller burden.
  4. Define interfaces before implementation. For each module, document purpose, public operations, inputs, outputs, errors, invariants, side effects, caller responsibilities, hidden knowledge, and non-goals.
  5. Audit the design. Check for shallow modules, leakage, pass-through methods or variables, duplicate abstractions across layers, temporal decomposition, boolean-flag APIs, special-case spread, and fragile call ordering.
  6. Choose the design with the lowest total complexity. Prefer one deeper module over several shallow modules when separation only exports coordination burden.
  7. Implement against the chosen contract. Keep public APIs minimal, push repeated caller burden downward, and update names/comments when the abstraction becomes clearer.
  8. Report the architectural result. Summarize what complexity was hidden, which interfaces were created or changed, what alternatives were rejected, and what tradeoffs remain.

Decision Rules Summary

  • Prefer fewer, more powerful operations over many tiny methods.
  • Name APIs by caller intent, not implementation steps.
  • Expose domain concepts and stable value types, not tables, rows, framework objects, vendor DTOs, transport objects, or raw status codes.
  • Split modules when they hide different knowledge or change for different reasons.
  • Merge modules when the split creates pass-through APIs, shared private knowledge, or caller-managed sequencing.
  • Each layer must provide a different abstraction; do not duplicate the same CRUD-shaped interface across controller/service/manager/repository layers.
  • Pull complexity downward when it eliminates repeated caller logic or hides volatile decisions; stop when the abstraction becomes speculative, surprising, or god-object-like.
  • Design errors and special cases out of existence when possible through defaults, normalization, invariants, or domain concepts.
  • Expose only errors that callers can act on.
  • Treat comments and names as part of the interface design.

Mandatory Design Gates

Before coding, answer:

1. What total complexity does this design reduce?
2. Which module is deepest, and why?
3. What implementation knowledge is hidden?
4. What is the smallest useful public interface?
5. What are the rejected alternatives?
6. Where could information leak?
7. Are there pass-through methods or pass-through variables?
8. Do layers use distinct abstractions?
9. Are special cases centralized or designed away?
10. What future change should be easier after this design?

If answers are weak, revise the design before coding.

Applying to a Specific Coding Task

When the user asks for implementation, first produce the design brief unless the task is trivial. Then implement only the selected design. During coding, stop and revise the design if you introduce a pass-through API, leak implementation details across a boundary, duplicate a layer abstraction, or add caller-visible special-case sequencing.

Critiquing Existing Architecture

When asked to review existing code or architecture, use templates/architecture-critique.md. Focus on complexity symptoms first: change amplification, cognitive load, hidden coupling, unknown unknowns, leakage, pass-throughs, shallow modules, temporal decomposition, and duplicated layer abstractions. Recommend small strategic refactorings before broad rewrites.

skills

modular-software-design-skill

SKILL.md

tile.json