This guide explains how Reflow is developed and maintained.
It serves as the primary reference for contributors and maintainers.
Topics include:
- Architecture principles
- Coding standards
- Testing philosophy
- Refactoring guidelines
- Documentation standards
Reflow follows several core principles:
Simple
Testable
Maintainable
Extensible
When introducing new features, prefer:
Small changes
Clear responsibilities
Incremental refactoring
over large rewrites.
Reflow follows a layered architecture.
CLI
↓
Resolver
↓
Core
↓
Service
↓
Executor
↓
External Tool
Each layer has a specific responsibility.
Location:
app/cli/
Responsibilities:
Commands
Options
Help messages
Presentation
The CLI should not contain business logic.
Preferred:
CLI
↓
Resolver
↓
Core
Avoid:
CLI
↓
Business Logic
Location:
app/cli/**/resolver.py
Responsibilities:
Configuration loading
Option resolution
Argument transformation
Validation
Resolvers prepare data for the core layer.
Location:
app/core/
Responsibilities:
Business rules
Workflows
Application behavior
The core layer should not depend on Typer or Rich.
Responsibilities:
Git operations
Docker operations
Release operations
Services expose high-level actions.
Example:
GitService
DockerService
Responsibilities:
Command execution
Process handling
External tool invocation
Executors are the boundary between Reflow and external tools.
Preferred:
CLI
↓
Core
↓
Service
↓
Executor
Avoid:
Executor
↓
CLI
Dependencies should flow downward.
Always use type annotations.
Preferred:
def convert_tag(tag: str) -> str:
...Avoid:
def convert_tag(tag):
...Public functions should include docstrings.
Preferred structure:
"""
Convert a tag to SemVer format.
Workflow:
1. Read source tag
2. Convert version
3. Create new tag
4. Return result
"""Workflow sections are encouraged when behavior is non-trivial.
Use descriptive names.
Preferred:
converted_tag
resolved_config
docker_serviceAvoid:
tmp
x
data2Before refactoring:
Understand behavior
Write tests
Preserve functionality
Refactoring should not change behavior unless explicitly intended.
Extract Function
↓
Extract Class
↓
Move Responsibility
↓
Simplify
Avoid large rewrites when smaller steps are possible.
Reflow emphasizes:
Behavior
Coverage
Maintainability
Tests should verify behavior rather than implementation details.
def test_convert_tag() -> None:
...Use clear names that describe behavior.
Target:
90%+
Core workflows should ideally reach:
100%
when practical.
Documentation should answer:
What?
Why?
How?
before discussing implementation details.
Preferred:
Overview
Workflow
Examples
FAQ
This structure is used throughout Reflow.
Examples:
docs/init/
docs/tags/
docs/dockerize/
Location:
app/ui/
Preferred:
Panels
Tables
Progress bars
Avoid:
Raw print statements
Repeated formatting
Use shared UI helpers whenever possible.
Configuration should live in:
config.toml
Avoid scattering configuration across multiple files.
Prefer:
Specific exceptions
Example:
except ReflowError:
...Avoid:
except Exception:
...unless absolutely necessary.
Recommended workflow:
Command
↓
Resolver
↓
Models
↓
Core
↓
Tests
Avoid placing business logic directly in command files.
Before opening a pull request:
✓ Tests pass
✓ Ruff passes
✓ Documentation updated
✓ Help messages updated
✓ Behavior preserved
New contributors should read:
developer-guide/getting-started.md
then:
architecture/workflow.md
then:
architecture/design-patterns.md
Architecture:
docs/architecture/
Testing:
docs/testing/testing-guide.md
Roadmap:
docs/project/roadmap.md
The most important rule is:
Keep responsibilities separated.
Follow the architecture layers, preserve behavior during refactoring, and keep the codebase simple and maintainable.