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.

93

1.12x
Quality

94%

Does it follow best practices?

Impact

92%

1.12x

Average score across 5 eval scenarios

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 references/design-brief-template.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 and Design Gates

Use references/decision-rules.md for the full split/merge, leakage, layering, error, and naming rules. 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 references/architecture-critique-template.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.

tile.json