Organize all product strategy and domain modeling documentation into a dedicated .product-strategy directory for better separation from code. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
12 KiB
Aether Product Strategy Chain
This directory contains the complete product strategy chain for Aether, from organizational values to executable work.
The Chain (Product Strategy Framework)
Manifesto (Flowmade values)
↓ (constraints + outcomes)
vision.md (what Aether does)
↓ (events + decisions)
PROBLEM_MAP.md (problem space)
↓ (boundaries)
BOUNDED_CONTEXT_MAP.md (domain boundaries)
↓ (invariants)
Domain Models (not yet; next step)
↓ (system abilities)
Capabilities (not yet; next step)
↓ (user value)
Features (not yet; next step)
↓ (executable)
Issues (not yet; generated from features)
Documents in This Repository
1. vision.md
What: Product vision statement Answers:
- Who is Aether for? (Go teams building event-sourced systems; Flowmade internally)
- What pain does it solve? (Distributed event sourcing without heavyweight frameworks)
- What won't we do? (No opinionated multi-tenancy, no domain modeling, no UI)
Output: 1-page product promise
2. PROBLEM_MAP.md
What: Problem space analysis through developer journeys Covers:
- 4 developer journeys (single-node, scaling, namespace isolation, concurrency)
- 25+ business events across domains
- 6 decision points with trade-offs
- 6 risk areas with expensive mistakes
- Code observations (intended vs actual implementation)
Key Insight: Don't start with DDD; first understand the problem from users' perspective
Output: Timeline of events, decisions, risks (no entities yet)
3. BOUNDED_CONTEXT_MAP.md
What: Domain boundaries identified from problem space Contains:
- 5 bounded contexts (Event Sourcing, Optimistic Concurrency, Namespace Isolation, Cluster Coordination, Event Bus)
- For each context:
- Purpose & core responsibility
- Ubiquitous language (domain vocabulary)
- Key entities & events
- Interfaces to other contexts
- Lifecycle patterns
- Current code locations
- Alignment with vision
- Gaps & observations
- Context relationships (producer/consumer, dependencies, orthogonal patterns)
- Boundary rules (language, lifecycle, ownership, scaling)
- Code alignment analysis (intended vs actual)
- Refactoring backlog
Key Insight: Boundaries cut by language differences, lifecycle differences, ownership, and scaling needs
Output: Clear domain boundaries; ready for aggregates & invariants
4. CONTEXT_MAP_DIAGRAM.md
What: Visual representation of bounded contexts Contains:
- ASCII diagram of 5 contexts
- Single-node system interaction
- Multi-node cluster interaction
- Multi-tenant scenario
- Ownership matrix
- Lifecycle timelines (events, shards, subscriptions)
- Invariants per context
- Dependency summary
- Testing strategy
Output: Visual clarity; communication tool for team discussions
Next Steps in Strategy Chain
Step 4: Domain Models (per context)
Goal: Capture business invariants and define aggregates
For each bounded context:
- Identify invariants ("what must never break?")
- Define aggregates (clusters of entities that must be consistent)
- Define commands (intent to change state)
- Define events (facts that happened)
- Define value objects (immutable, identity-less concepts)
- Define read models (views optimized for queries)
Example for Event Sourcing context:
- Aggregate: ActorEventLog (root); contains Events
- Invariant: "Version must be strictly monotonic"
- Commands: SaveEvent (internal), ApplySnapshot
- Events: EventStored, VersionConflict, SnapshotCreated
- Value Objects: Version, EventType, Timestamp
Deliverable: Domain models document per context
Step 5: Capabilities (system abilities)
Goal: Bridge domain thinking to roadmap thinking
For each domain model:
- "Store events durably with conflict detection" (Event Sourcing)
- "Detect concurrent writes and fail fast" (Optimistic Concurrency)
- "Isolate logical domains using namespace patterns" (Namespace Isolation)
- "Distribute actors across cluster nodes" (Cluster Coordination)
- "Route events to subscribers with filtering" (Event Bus)
Rule: Capabilities survive UI rewrites; they're about what the system CAN DO
Deliverable: Capability map
Step 6: Features
Goal: Define user-visible value slices
Process:
- What capability does this feature enable?
- Who needs it? (user persona)
- Why now? (market/business reason)
- How do you demo it?
Example features:
- "Developer can save events to in-memory store for fast iteration"
- "Developer can scale single-node system to cluster without rewriting"
- "Operator can configure namespace prefixes for multi-tenant isolation"
- "Leader automatically elected on cluster formation"
- "Subscriber can filter events by type and actor pattern"
Deliverable: Feature list with business context
Step 7: Issues (executable work)
Goal: Decompose features into implementable tasks
Structure per issue:
- User story: "As a [who], I want [what], so that [why]"
- Acceptance criteria: "Given [context], when [action], then [outcome]"
- Domain reference: Link to bounded context, aggregate, invariant
- Technical approach: What commands/events/queries involved
Example issue:
User Story: As a developer, I want to save events with automatic version conflict detection,
so that concurrent writes don't silently lose data.
Acceptance Criteria:
1. SaveEvent validates version > current latest
2. Returns VersionConflictError with ActorID, attempted, current versions
3. GetLatestVersion returns 0 for new actors
4. Conflict detection is fast (<1ms per write)
Linked to: Bounded Context: Event Sourcing
Aggregate: ActorEventLog
Invariant: Monotonic versions
Event: VersionConflict
Deliverable: GitHub issues with domain language
How to Use This Chain
For Technical Decisions
- Read vision.md - What are we building? Why?
- Read PROBLEM_MAP.md - What are users trying to do?
- Read BOUNDED_CONTEXT_MAP.md - What are the boundaries?
- Identify which context your decision touches
- Check: Does it violate a context invariant?
For New Contributors
- Start with vision.md (2 min read)
- Read the 4 journeys in PROBLEM_MAP.md (10 min)
- Focus on relevant context in BOUNDED_CONTEXT_MAP.md (10 min)
- Refer to CONTEXT_MAP_DIAGRAM.md when confused about interactions
For Roadmap Planning
- Current state: BOUNDED_CONTEXT_MAP.md identifies gaps
- Define domain models per context (Step 4)
- List capabilities (Step 5)
- Prioritize features (Step 6)
- Break into issues (Step 7)
For Code Review
- Does this code touch multiple bounded contexts?
- If yes: Are boundaries clear? Is translation happening at seam?
- Does this change a context's invariant?
- If yes: Is new invariant documented?
- Does this add new language (terms)?
- If yes: In which context? Is it consistent?
Key Principles (from Vision)
Primitives Over Frameworks
- Aether provides composition points (interfaces), not opinions
- Each context has clear boundaries; app wires them together
- Example: SaveEvent returns error; app decides retry strategy
NATS-Native
- Built for JetStream from the start
- Event distribution, durability, and clustering all via NATS
- Not a bolted-on abstraction
Resource Conscious
- Efficient on modest hardware
- ARM64 friendly
- No heavy dependencies
Events as Complete History
- Events are source of truth
- State is derived by replay
- Audit trail is native
Boundary Rules (Summary)
Language Boundaries
Different terms → Different contexts. Example:
- "Event" in Event Sourcing = immutable fact
- "Event" in CQRS read models = notification of change
- These are different concepts; keep separate
Lifecycle Boundaries
Different timescales → Different contexts. Example:
- Event lifetime: Create → Persist → Replay forever
- Shard lifetime: Assign → Migrate → Reassign
- These have different operations; different contexts
Ownership Boundaries
Different owners → Different contexts. Example:
- Event Sourcing: App writes events; Library stores
- Cluster Coordination: Library manages; App doesn't directly control
- Each context has clear ownership
Scaling Boundaries
Different performance needs → Different contexts. Example:
- Event Bus: Must be fast (us); non-blocking
- Cluster Coordination: Can be slow (seconds); eventual consistency OK
- Different scaling strategies
How Bounded Contexts Emerged
From Problem Space
- Event Sourcing journey → Events are facts, versions matter, replay needed
- Scaling journey → Cluster leadership, shard distribution needed
- Namespace journey → Isolation patterns, wildcard risks
- Concurrency journey → Version conflicts, retry strategy needed
- Distribution journey → Event bus, cross-node routing needed
Cut by Boundaries
- Language: Each journey uses different terms
- Lifecycle: Events persist forever; leases expire; subscriptions created/destroyed
- Ownership: App writes events; Library coordinates cluster; App filters subscriptions
- Scaling: Single actor scales by snapshots; cluster scales by shards; bus scales by subscribers
Validated Against Code
- Each context has dedicated module(s)
- Code structure aligns with intended boundaries
- Gaps identified (actor migration, snapshot strategy, namespace validation)
Anti-Patterns Avoided
| Anti-Pattern | What Aether Does Instead | Why |
|---|---|---|
| One big event model | Generic Event struct; domain language in strings | Primitives approach |
| Automatic retry on conflict | Return error to app | App owns retry strategy |
| Opinionated multi-tenancy | Namespace primitives; app defines semantics | Avoid framework opinions |
| Wildcard subscriptions default | Explicit namespace; wildcard opt-in with warnings | Security-first |
| Shared state across contexts | Events flow between contexts; each owns its data | Clean boundaries |
Decision Gates
After vision: Can you crisply answer who/what/why?
- ✓ Aether: For Go teams; removes distributed complexity; no framework opinions
After problem space: Do you see events, not just CRUD?
- ✓ Aether: 25+ business events across 4 journeys; clear decisions and risks
After contexts: Are boundaries clear?
- ✓ Aether: 5 contexts with distinct language, lifecycle, ownership, scaling
After domain models: Does each aggregate enforce an invariant?
- → Next step (not yet done)
After capabilities: Can each capability be demoed?
- → Next step (not yet done)
After features: Does each feature move a capability?
- → Next step (not yet done)
Related Documents
- Organization Manifesto: flowmade-one/architecture/manifesto.md - Who Flowmade is; what we believe
- Repository Map: flowmade-one/architecture/repos.md - How Aether fits in Flowmade ecosystem
- README.md: Quick start, setup, architecture
- CLAUDE.md: Development instructions for AI assistants
Summary
Aether is at Step 3 of the strategy chain: Bounded Contexts Identified.
What's done:
- Vision: Clear product promise (primitives for distributed event sourcing)
- Problem space: 4 journeys, 25+ events, 6 decisions, 6 risks
- Bounded contexts: 5 contexts with clear boundaries; code aligns
What's next:
- Domain models: Define aggregates and invariants per context
- Capabilities: System abilities (what can developers do?)
- Features: User value slices (what's on the roadmap?)
- Issues: Executable work (what's the next sprint?)
Team alignment: Use BOUNDED_CONTEXT_MAP.md + CONTEXT_MAP_DIAGRAM.md to verify all stakeholders understand the domain boundaries before diving into implementation.