Move product strategy documentation to .product-strategy directory
Some checks failed
CI / build (push) Successful in 21s
CI / integration (push) Failing after 2m1s

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>
This commit is contained in:
2026-01-12 23:57:11 +01:00
parent 18ea677585
commit 271f5db444
26 changed files with 16521 additions and 0 deletions

View File

@@ -0,0 +1,348 @@
# 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](./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](./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](./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](./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:**
1. Identify invariants ("what must never break?")
2. Define aggregates (clusters of entities that must be consistent)
3. Define commands (intent to change state)
4. Define events (facts that happened)
5. Define value objects (immutable, identity-less concepts)
6. 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:**
1. What capability does this feature enable?
2. Who needs it? (user persona)
3. Why now? (market/business reason)
4. 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
1. Read **vision.md** - What are we building? Why?
2. Read **PROBLEM_MAP.md** - What are users trying to do?
3. Read **BOUNDED_CONTEXT_MAP.md** - What are the boundaries?
4. Identify which context your decision touches
5. Check: Does it violate a context invariant?
### For New Contributors
1. Start with **vision.md** (2 min read)
2. Read the 4 journeys in **PROBLEM_MAP.md** (10 min)
3. Focus on relevant context in **BOUNDED_CONTEXT_MAP.md** (10 min)
4. Refer to **CONTEXT_MAP_DIAGRAM.md** when confused about interactions
### For Roadmap Planning
1. Current state: BOUNDED_CONTEXT_MAP.md identifies gaps
2. Define domain models per context (Step 4)
3. List capabilities (Step 5)
4. Prioritize features (Step 6)
5. Break into issues (Step 7)
### For Code Review
1. Does this code touch multiple bounded contexts?
- If yes: Are boundaries clear? Is translation happening at seam?
2. Does this change a context's invariant?
- If yes: Is new invariant documented?
3. 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
1. **Event Sourcing journey** → Events are facts, versions matter, replay needed
2. **Scaling journey** → Cluster leadership, shard distribution needed
3. **Namespace journey** → Isolation patterns, wildcard risks
4. **Concurrency journey** → Version conflicts, retry strategy needed
5. **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](https://git.flowmade.one/flowmade-one/architecture/src/branch/main/manifesto.md) - Who Flowmade is; what we believe
- **Repository Map**: [flowmade-one/architecture/repos.md](https://git.flowmade.one/flowmade-one/architecture/src/branch/main/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.