SuperAPI AI Directory

package-design

Coding & development

View repository

Updated 10-16 09:57

About this skill

Package Design Skill

Reorganize messy code into well-structured packages through systematic analysis.

Core: Package design is not a matter of "where to place source code" but a design problem of "where to stop the waves of change" and "how to control the direction of dependencies".

Core Workflow

Phase 1: Analyzing Reasons for Change - Finding the Starting Point for Splitting

The starting point for splitting is not "procedural steps" but "design decisions likely to change".

Based on Parnas' information hiding, first ask the following:

  • "What changes?"(Enumerate reasons for change and sources of change)
  • "When it changes, how far may it involve other things?"(Release unit and responsibility boundaries)
  1. Analyze the change history (git log) of the target code and identify groups of files that are changed together
  2. Organize the scope of impact for each external factor (UI changes, DB changes, API changes, business rule changes)
  3. For each reason for change, tentatively place boundary candidates such that "this change should be closed here"

Output: A correspondence table of reasons for change and scope of impact

Phase 2: Chunk Down (Decomposition) - Identifying Responsibilities

Extract atomic responsibilities from the target code:

  1. List all public types, functions, and traits
  2. Write a "one-sentence responsibility description" for each element
  3. Identify implicit responsibilities (error handling, logging, configuration, etc.)
  4. Flag elements with multiple responsibilities (SRP violations)

Output: A list of 10 to 50 atomic responsibilities

Phase 3: Grouping - Creating Candidate Packages

Select axes for splitting responsibilities and group them.

Selecting Split Axes

Split Axis Nature of Cohesion Suitable Cases Risk
Feature (feature/vertical) Changes close vertically Team independence, microservice candidates Commonization hell
Domain (business concept) Informational cohesion Emphasis on consistency of the domain model Translation cost between contexts
Layer (technical layer) Separation of technical responsibilities Small scale, early adoption One change scatters across all layers
Responsibility (reason for change) CCP compliant Change frequency is clear Initial analysis cost
API boundary (public interface) Minimize surface area Library design Balance with internal flexibility

Grouping Heuristics

  • Elements that change together → same package (CCP)
  • Elements reused together → same package (CRP)
  • Boundaries of domain concepts → natural package boundaries

Output: 3–7 candidate packages (7±2 is a guideline from the perspective of cognitive load)

Validation by MECE (as a checking perspective, not a design goal)

Use MECE not as a "design purpose" but as an "aid for completeness checking". If you stick too strictly to MECE, there is a risk that boundaries become blurred in handling cross-cutting concerns (logging, authorization, transactions, etc.). 80–90% coverage is sufficient.

  • Is each responsibility assigned to exactly one package (no duplication)?
  • Are there no unassigned responsibilities left (no omissions)?
  • Is there exactly one answer to "Where should X go?"

For details, see references/principles.md#mece-分割 .

Phase 4: Chunk Up - Abstraction and Naming

Abstract each group by one level and name it:

  1. Find the concept that runs through each group
  2. Name by domain concept, not by technical role
  3. Confirm that you can state the purpose of that package in one sentence
  4. If naming is difficult, the grouping is likely wrong → return to Phase 3

Good example: authentication, billing, inventory Examples to avoid: utils, helpers, common, misc

Phase 5: Dependency Design and Principle Validation

Design the direction of dependencies

Direct dependencies toward the "more stable, more abstract" side.

  1. Draw the dependency graph between packages
  2. Check for circular dependencies (ADP)
  3. Check whether dependencies are reversed from the stable side (depended on by many) to the unstable side (depends on many) (SDP)
  4. Check whether stable packages are sufficiently abstract (SAP)

Procedure for resolving circular dependencies

If a cycle is found:

  1. Dependency inversion: Move the abstraction (Interface/Trait) of the depended-on side to the depending side, and inject the implementation in the reverse direction
  2. Shared extraction: Move mutually referenced common types/logic to a third package and cut the cycle edge
  3. Integration: If they truly are the same responsibility, integrate the packages

Principle check

Principle Check perspective
High cohesion Do the elements within the package converge on a single purpose?
Low coupling Are dependencies between packages minimized?
ADP Are there no circular dependencies?
SDP Are dependencies directed toward the stable side?
SAP Are stable packages sufficiently abstract?
CCP Whether changes with the same reason for change are confined to the same package

For details, see references/principles.md .

Phase 6: Defining Public Interfaces and Test Boundaries

Public Interfaces

For each package:

  1. pub Identify the elements that should be (external contracts)
  2. Everything else should be pub(crate) make it private
  3. If the interface is complex, provide facade types/functions
  4. Explain the contract in module documentation

Mapping Test Boundaries

Map tests to "boundaries":

Test Type Target Purpose
Unit Test Package internals Preserve internal cohesion
Integration tests Between packages Whether cross-boundary dependencies are as designed
Contract tests Public API boundaries Preserve compatibility (integration points)

Evaluation Checklist

Check whether the proposed structure satisfies the following (the more Yes answers, the higher the cohesion and lower the coupling):

  • The purpose of each package can be stated in one sentence (what it provides and what it hides)
  • Dependencies that cross boundaries go through public APIs (facades/ports)
  • The package dependency graph is acyclic
  • Highly stable areas are sufficiently abstracted
  • Reasons for change stop at package boundaries
  • Boundary tests match the scope of the public API

Quantitative Evaluation Using Metrics

Metrics Target Meaning
Ca (afferent coupling) Package Number of external dependents
Ce (efferent coupling) Package Number of external dependencies
I = Ce/(Ca+Ce) Package Instability (0 = most stable, 1 = most unstable)
D (distance from the Main Sequence) Package Deviation from A + I = 1

For details, see references/principles.md#パッケージメトリクス .

Refactoring Triggers

If the following are observed, consider reviewing the split/boundaries:

  • Changes are scattered across multiple packages (a sign of CCP violation)
  • Ce increases (external dependencies keep growing)
  • Package cycles (circular dependencies) occur
  • Complexity within a package keeps increasing

Rust-Specific Patterns

references/rust-patterns.md See:

  • mod Hierarchical design
  • Choosing between a workspace and a single crate
  • Feature flag strategy
  • Guidelines for re-exports

※ In this project Do not use mod.rs. With the 2018 module system, package_name.rs と package_name/ Configure with files under

Comparison of Representative Patterns

Pattern Cohesion axis Advantages Risk
Layered Technical responsibility Easy to introduce 1 change is scattered across all layers
By feature (vertical slicing) Use Case Changes are easy to close Commonalization hell
By component Feature set Clear boundaries Public API design cost
Bounded Context Domain boundaries Model consistency Inter-context translation cost
Ports & Adapters / Clean Dependency direction Testability Structural formalism

Anti-pattern

  • God module: Responsibilities exceeding 500 lines are concentrated in 1 file
  • Circular dependency: A → B → C → A (a signal that boundaries have effectively collapsed)
  • Unstable dependency: Core modules depend on modules that change frequently (SDP violation)
  • Leaky abstraction: Internal types leak into the public API
  • Miscellaneous util/common: Loosely related elements are aggregated under "other" (a breeding ground for common coupling)
  • Layers only, no boundaries: Even if it looks layered, cross-references and internal references are left unchecked
  • cargo cult packaging: Patterns are applied without understanding the reasons, and although the structure looks organized, the intent is lost

Output format

Restructuring proposals are presented in the following format:

## 提案パッケージ構成

package_name.rs (目的: 1文で説明)
package_name/
├── submodule_a.rs
└── submodule_b.rs

### 依存関係
package_a → package_b (reason)

### メトリクス概算
package_a: Ca=3, Ce=1, I=0.25 (安定)
package_b: Ca=1, Ce=2, I=0.67 (不安定)

### 移行手順
1. 新しいモジュール構造を作成する
2. 型や関数を最小変更で移動する
3. import を更新する
4. テストが通ることを確認する
5. 循環依存がないことを静的解析で確認する

Related skills (recommended for co-reading)

When using this skill, also refer to the following skills:

  • ddd-module-pattern: Domain vocabulary-based module design in a DDD context
  • refactoring-packages: Executing refactoring of existing package structures
  • clean-architecture: The 4-layer architecture that forms the foundation of package design