About this run
Run
- Id
- d3142150-bc02-4660-9022-aebab8777750
- Prompt
- E-commerce monolith migration
- Configuration
- cheap 3x2
- Loaded from
- slow-thinker.keys.json ← slow-thinker.base.json ← slow-thinker.cheap.json
- Made with
- Process executor
- This page
- Report generator 0.1.16 · Analysis generator
- Status
- completed
- Started
- 2026-09-19 02:49
- Duration
- 8 min 0 s
Council
- Proposers
- 3
- Refinement rounds
- 2
- Voters
- 3
- Selected plan
- claudeHaiku4.5_refine_1 · 2 of 3 votes · 20 steps
Plan cost
Analysis LLM analysis
Models of the council
| Model | Thinking |
|---|---|
| claudeHaiku4.5 · anthropic/claude-haiku-4-5 | extended thinking, 15.0k tokens · temp 1 |
| deepseek-flash · deepseek/deepseek-flash | thinking on, effort low |
| qwen3.8-flash · alibaba/qwen3.8-flash | thinking on, budget 4.0k tokens |
Analyses of this run
| # | Date | Analyst | Schema | Analysis generator | Calls | Cost | Verdict on the vote | Report |
|---|---|---|---|---|---|---|---|---|
| 2 | 2026-09-20 20:58 | alibaba/qwen3.7-plus |
v5 | not recorded slow-thinker 0.1.0 |
5 | 0.094 USD | disagrees | open |
| 1 | 2026-09-19 03:03 | alibaba/qwen3.7-plus |
v4 | not recorded slow-thinker not recorded |
5 | 0.086 USD | disagrees | this page |
Task
A mid-size European fashion retailer runs its e-commerce on a 10-year-old monolith: Java 8 / Spring, about 2 million lines, one PostgreSQL database of 1.2 TB with 350 tables and heavy use of stored procedures and cross-module joins. It serves 8 countries, 3 currencies and 4 languages, with about 40,000 orders a day and peaks of 12x during sales. The monolith contains: the storefront (server-rendered, plus a separate mobile app hitting the same endpoints), catalogue and search (a Lucene index rebuilt nightly), pricing and promotions (the most complex module, 200,000 lines, with country-specific rules nobody fully understands), cart and checkout with three payment providers, order management, inventory synchronised every 15 minutes with the warehouse system via file exchange, customer accounts and loyalty, returns, and a back-office used by 300 staff. Deployments happen every two weeks as a single artefact with a 30-minute maintenance window; test coverage is 25% and mostly unit tests. Five teams of 8 developers, each organised around a business area but all committing to the same repository.
Plan the migration to independently deployable services over 12 months with no feature freeze, no unplanned downtime and the ability to roll back every step, preserving the peak-season capacity (sales in January and July must not be put at risk).
Process
Round 0 — initial proposals
The agents proposed three migration strategies with distinct strengths. None fully address the 12-month timeline given the massive codebase.
- Proposal 1 is the most realistic regarding peak-season risks but delays extraction.
- Proposal 2 establishes a strong platform foundation but fatally delays team reorganization.
- Proposal 3 handles the pricing module pragmatically but lacks granular database details.
Overall, all plans lack sufficient detail on data migration runbooks for the database.
The calls of this round
This plan outlines a 24-step process starting with extensive documentation and test coverage improvements before any code extraction. It extracts services incrementally, beginning with read-heavy modules like Search and moving to complex domains like Pricing and Checkout.
The strategy heavily relies on dual-write patterns and strict rollback procedures to protect peak sales seasons. However, increasing test coverage to 70% before extraction will likely consume too much of the 12-month timeline.
The plan produced
1. Current State Documentation & Target Architecture
Create a detailed map of the monolith to inform service extraction strategy.
- Audit all modules: storefront, catalogue, search, pricing/promotions, cart, checkout, orders, inventory, customers, loyalty, returns, back-office
- Map dependencies between modules, identifying cross-module calls and data flows
- Model future bounded contexts using Domain-Driven Design
- Create technology inventory (libraries, frameworks, protocols)
- Document interface contracts for each module
- Identify which teams own which modules for organizational alignment
2. Data Dependency Analysis & Dual-Write Strategy (after 1)
Untangle the 1.2TB database to support service independence without blocking progress.
- Map all 350 tables to future service domains
- Identify cross-service joins and stored procedures that span domains
- Design per-service database schemas with minimal denormalization
- Create data versioning framework to support rollback
- Plan dual-write patterns: how old monolith and new services will sync during transition
- Document eventual-consistency requirements and conflict resolution
- Design data migration runbooks with clear rollback steps
3. Test Coverage Audit & Improvement Roadmap (after 1)
Build confidence for service extraction by eliminating test blindness.
- Audit current 25% test coverage by module
- Identify coverage gaps in modules scheduled for early extraction
- Establish target of 70%+ coverage for modules being extracted
- Prioritize integration tests over unit tests given monolith complexity
- Create quality gates: no service extraction below 60% module coverage
- Plan for continuous improvement during extraction phases
4. Peak-Season Window Planning & Risk Framework (after 1)
Protect January and July sales by scheduling extractions during safe windows.
- Map annual peak periods: January sales (peak orders), July sales, plus any promotional events
- Define 4-week freeze windows before/during peaks
- Identify lowest-risk windows in each month for major changes
- Create rollback procedures that execute in <30 minutes
- Establish monitoring escalation for changes made near peak season
- Document communication plan with business teams
5. Observability Foundation Setup
Instrument the system for real-time visibility during migration.
- Deploy centralized logging (ELK, Splunk, or similar)
- Set up metrics collection (Prometheus, Datadog, or similar)
- Implement distributed tracing (Jaeger, Zipkin) for request flows across services
- Create dashboards for: requests/sec, error rates, latency percentiles, database load
- Define SLOs: order processing latency p99, checkout success rate, payment authorization speed
- Set up alerts for SLO violations and anomalies
6. Feature Flags, Containerization & API Gateway
Build the technical foundation for canary deployments and controlled traffic routing.
- Implement feature flag system (LaunchDarkly, custom Spring Boot solution, etc.)
- Containerize monolith and all new services (Docker)
- Set up container orchestration (Kubernetes or similar) with service templates
- Deploy API gateway (Kong, AWS ALB) with routing rules
- Implement service-to-service authentication (mTLS, JWT)
- Configure rate limiting and circuit breakers at gateway
7. Deployment Pipeline & Automated Rollback (after 6)
Enable safe, automated deployments with reliable rollback capability.
- Implement CI/CD pipeline with automated testing gates
- Set up blue-green deployment: run old and new versions in parallel, switch traffic atomically
- Build canary deployment capability: route 5%→10%→50%→100% of traffic gradually
- Automate rollback: trigger on error rate threshold, latency spike, or manual command
- Create deployment runbooks for each service
- All deployments must be independent; monolith keeps 2-week cycle until fully extracted
8. Test Coverage Improvement to 70%+ (after 3)
Close test gaps before extracting services to reduce rollback risk.
- Implement integration tests for key flows: order creation, payment processing, inventory updates
- Add contract tests between modules to catch breaking changes
- Use mutation testing to verify test quality
- Target 70%+ coverage for: pricing module, payment module, order management
- Establish automated quality gates: coverage <70% blocks extraction of that service
- Include tests for peak-load scenarios (40k→480k orders)
9. Search/Catalogue Service Extraction & Validation (after 3, 7, 8)
Extract the first service: search is read-heavy, isolated, and low-risk.
- Extract catalogue and search indexing logic from monolith
- Build as independent Spring Boot service with own codebase/deployment
- Create new database schema for catalogue (subset of 350 tables)
- Implement dual-write: monolith writes to both old Lucene index and new service
- Implement canary routing: API gateway sends 10% of search requests to new service, monitor latency and correctness
- Validate results match between old and new service (checksums on result sets)
- Gradually increase traffic: 10%→25%→50%→100%
- Keep dual-write active for 2 weeks post-cutover for rollback safety
10. Event Bus & Service Mesh Infrastructure (after 9)
Build async communication layer required for multi-service coordination.
- Deploy message broker (Kafka recommended for ordering guarantees and peak load of 40k/sec)
- Define domain events: OrderPlaced, PaymentAuthorized, InventoryReserved, etc.
- Implement event schema versioning and compatibility
- Set up service discovery (Consul, Kubernetes DNS)
- Implement distributed configuration management
- Create event publishing library for services to use
- Document saga patterns for multi-step workflows
- Test message broker under peak load (480k messages/day)
11. Inventory Service Extraction & Warehouse Sync (after 10)
Extract inventory as second service: well-bounded, drives warehouse sync complexity.
- Extract inventory logic and reservation system
- Build inventory service with own database schema
- Implement dual-write from monolith to both old and new inventory data
- Preserve existing 15-minute warehouse file exchange, but now via service
- Create inventory events: ReservationCreated, ReleaseRequested
- Implement canary rollout: gradual traffic shift like search service
- Test warehouse sync under peak load
- Validate inventory consistency across monolith and new service before full cutover
12. Customer/Loyalty Service Extraction & Auth Refactoring (after 10)
Extract customer accounts and loyalty: enables independent scaling of auth layer.
- Extract customer account and loyalty program logic
- Build customer service with own database schema
- Separate authentication from monolith: implement API for token validation
- Support multi-tenant loyalty rules (8 countries, country-specific points rules)
- Implement canary rollout with real customer sessions
- Create backwards-compatible customer APIs
- Test account operations at peak concurrency (concurrent logins, loyalty point updates)
- Plan for session management: ensure distributed sessions work across services
13. Saga Pattern Library & Order Orchestration Framework (after 10)
Build the framework for managing distributed transactions across services.
- Implement saga pattern library: choreography-based (event-driven) and orchestration-based patterns
- Support compensating transactions: if payment fails, return inventory reservation
- Handle timeouts and retries with exponential backoff
- Implement idempotency keys to prevent duplicate charges on retries
- Test saga execution under peak load and network failures
- Document patterns for: order placement saga, payment saga, return saga
- Create distributed tracing for saga flows
14. Pricing/Promotions Service Extraction (Phase 1: Extract As-Is) (after 13)
Begin extraction of most complex module (200k LOC) without initial refactoring.
- Extract pricing engine as-is with minimal refactoring to reduce initial risk
- Preserve all country-specific rules and business logic
- Build service boundary: accept pricing requests, return prices/promotions
- Create feature tests that document all 200k LOC behavior
- Map all promotion types to test scenarios
- Test with real country/currency/language combinations
- Implement as service behind same interface initially
- Prepare for Phase 2 refactoring once stable in production
15. Pricing/Promotions Service Refinement (Phase 2: Rules Refactoring) (after 14)
Gradually improve pricing service maintainability without breaking production.
- Document the 200k LOC of complex rules in machine-readable format
- Refactor rules engine into composable components
- Build DSL for country-specific promotion rules
- Decompose monolithic rule evaluation into smaller decision trees
- Use feature flags to A/B test refactored rules vs old implementation
- Optimize performance: reduce calculation time for promotions at checkout
- Validate that refactored logic matches original behavior across all countries
16. Payment Service Extraction & Security Hardening (after 13)
Extract payment processing with extreme rigor given PCI/regulatory requirements.
- Separate payment logic from checkout: payment validation, three-provider integration
- Build payment service with encrypted credential storage, no raw card data in logs
- Implement fraud detection integration and decline handling
- Audit for PCI-DSS compliance: minimal data exposure, encrypted transport
- Implement E2E testing for all three payment provider scenarios
- Load test payment service: 500+ payments/sec at peak
- Implement idempotent payment requests: prevent double-charging on failures
- Create detailed rollback procedures: how to fall back to direct monolith payment handling
17. Order Service Extraction & Event Stream (after 13, 16)
Extract order management: central service coordinating multiple workflows.
- Extract order creation, status tracking, and management logic
- Build order service with event stream: OrderCreated, PaymentAuthorized, InventoryReserved, OrderConfirmed
- Support order querying by all 5 teams (inventory, fulfillment, customer service, etc.)
- Implement order event sourcing for audit trail and replay capability
- Create order state machine: validate state transitions
- Test concurrent order processing at peak load (40k orders/day)
18. Checkout Service Composition via Saga (after 17)
Compose checkout from independent payment, inventory, and order services using sagas.
- Build checkout service that orchestrates: cart validation → pricing calculation → inventory reservation → payment authorization → order creation
- Use saga pattern: if payment fails, release inventory reservation automatically
- Implement distributed transaction semantics: all-or-nothing guarantee
- Support three payment providers transparently
- Test all failure scenarios: payment declines, inventory unavailable, warehouse system down
- Implement timeout handling: what happens if inventory service is slow at peak
- Validate checkout latency remains <5 seconds at peak load
19. Back-Office Integration with Service APIs (after 18)
Update back-office (used by 300 staff) to coordinate across all services.
- Create service aggregation endpoints: orders endpoint calls order service + payment service + inventory service
- Update back-office UI to call new service APIs instead of monolith
- Implement service discovery: handle service availability transparently
- Create caching layer: reduce latency for frequently accessed data
- Test with 300 concurrent staff users
- Implement search across all orders/customers via service APIs
- Add retry logic and timeouts to handle service failures gracefully
20. Storefront & Mobile App Refactoring (after 19)
Update client applications to use new service architecture transparently.
- Update server-rendered storefront templates to call service APIs
- Update mobile app endpoints (already separate, now points to services via gateway)
- Implement client-side caching: reduce latency impact of distributed calls
- Maintain backwards compatibility: old clients must still work
- Update API versioning: enable service changes without breaking clients
- Implement request tracing: correlate user requests across services
- Test storefront and mobile under peak load scenario (480k orders/day)
21. Legacy Database Deprecation & Data Migration (after 20)
Safely decommission the monolith database once all services are independent.
- Verify all data has been migrated to service-specific databases
- Maintain 2-week read-only access to old database for emergency queries
- Archive old database snapshots (regulatory requirement for order history)
- Update backup/recovery procedures: now per-service instead of monolith
- Verify no remaining cross-service joins depend on monolith schema
- Document data mapping for future reference
- Decommission old database infrastructure
22. Load Testing & Performance Optimization (after 21)
Validate new architecture meets production capacity requirements.
- Simulate peak load scenario: 480k orders/day (40k baseline × 12)
- Test across 8 countries, 3 currencies, 4 languages simultaneously
- Identify bottlenecks: service latency, database query performance, message broker throughput
- Optimize hot paths: pricing calculations, search queries, payment processing
- Test cache effectiveness: Lucene search response times, pricing cache hit rates
- Validate database connection pools don't exhaust under peak load
- Create load testing environment: realistic data, all 5 teams' concurrent usage
23. Documentation & Knowledge Transfer (after 22)
Codify migration experience and new architecture for long-term success.
- Document final service boundaries: APIs, responsibilities, data ownership
- Create operational runbooks: how to deploy each service, how to handle common failures
- Record architecture decision log: why services were split this way
- Document data consistency model: eventual consistency patterns used
- Create troubleshooting guides: common issues and resolutions
- Train each team on their service and API contracts with other services
- Record key decisions and trade-offs (e.g., why search is separate from catalogue, why pricing is monolithic within its service)
24. Production Stabilization & 30-Day Monitoring (after 23)
Establish stable operation and prove architecture meets requirements.
- Run 30-day monitoring period observing: error rates, latency, resource utilization
- Establish performance baselines: P99 latency per service, throughput, error rates
- Document SLO achievements: order processing speed, payment success rate, search latency
- Create incident playbooks based on observed issues
- Validate peak-load handling (Jan/July sales go normally through new architecture)
- Establish team on-call procedures for service alerts
- Plan for service scaling: autoscaling policies, capacity planning
- Complete full rollback verification: ensure rollback to monolith is always possible
- All 8 services independently deployed and running in production with zero unplanned downtime during 12-month migration
- Zero data inconsistencies between service-specific databases (validated by monthly reconciliation)
- January and July peak seasons proceed with no degradation: 480k orders/day processed within 5-second checkout SLA
- Test coverage increased from 25% to 70%+ for all extracted services
- Every service deployment is fully automated; manual rollback procedures tested and <30 minutes to execute
- Order processing latency (cart → confirmation) unchanged or improved: maintained under 5 seconds at peak load
- All 5 teams deploying independently: no cross-team deployment coordination required after cutover
- Pricing/promotions service successfully extracted with all 200k LOC of country-specific rules preserved and validated
- Search latency improved or maintained despite architectural change
- Inventory synchronization with warehouse continues reliably: no missed 15-minute sync cycles
- Back-office operations for 300 staff members unaffected by migration; service aggregation endpoints maintain <500ms latency
- Zero payment processing regressions: all three payment providers functioning, fraud detection active, PCI-DSS compliance maintained
[SYSTEM] You are an expert assistant in complex project planning. Your task is to generate a detailed and structured action plan to reach the main objective in the most professional and most detailed way, no matter how much work or steps will be needed to perform. Use your internal reasoning processes to think deeply about the problem and create the most comprehensive plan possible. Take as much time and space as you need to think through all aspects of the problem. After your thorough analysis, answer with the plan in the requested structure. Every text field you write will be read by a busy person, so write for them: short sentences, one idea each, in short paragraphs. Text fields accept Markdown: separate paragraphs with a blank line, use a bullet list when you enumerate things and plain paragraphs when you explain or argue, and bold at most one key phrase per paragraph. A text of more than three sentences must be split into paragraphs; never deliver a single unbroken block of text. [HUMAN] Main Objective: "A mid-size European fashion retailer runs its e-commerce on a 10-year-old monolith: Java 8 / Spring, about 2 million lines, one PostgreSQL database of 1.2 TB with 350 tables and heavy use of stored procedures and cross-module joins. It serves 8 countries, 3 currencies and 4 languages, with about 40,000 orders a day and peaks of 12x during sales. The monolith contains: the storefront (server-rendered, plus a separate mobile app hitting the same endpoints), catalogue and search (a Lucene index rebuilt nightly), pricing and promotions (the most complex module, 200,000 lines, with country-specific rules nobody fully understands), cart and checkout with three payment providers, order management, inventory synchronised every 15 minutes with the warehouse system via file exchange, customer accounts and loyalty, returns, and a back-office used by 300 staff. Deployments happen every two weeks as a single artefact with a 30-minute maintenance window; test coverage is 25% and mostly unit tests. Five teams of 8 developers, each organised around a business area but all committing to the same repository. Plan the migration to independently deployable services over 12 months with no feature freeze, no unplanned downtime and the ability to roll back every step, preserving the peak-season capacity (sales in January and July must not be put at risk)." Generate an initial, detailed, and well-structured plan proposal. The plan has these parts: - "steps": the list of steps, each with "step_id" (a short label unique within this proposal, such as S1, S2, S3), "title" (a short, descriptive title), "description" (what the step does and how, in Markdown: a short opening paragraph and then, if there are several concrete things to say, a bullet list) and "dependencies" (the step_ids of the other steps of THIS proposal that must be completed first; empty if none). - "estimated_complexity": "low", "medium" or "high". - "success_metrics": clear and measurable success metrics, one per line as a bullet list. Think deeply about the problem, considering all aspects and implications. Develop a comprehensive understanding of what needs to be done to achieve the objective, then produce the plan.
{"steps": [{"step_id": "S1", "title": "Current State Documentation & Target Architecture", "description": "Create a detailed map of the monolith to inform service extraction strategy.\n\n- Audit all modules: storefront, catalogue, search, pricing/promotions, cart, checkout, orders, inventory, customers, loyalty, returns, back-office\n- Map dependencies between modules, identifying cross-module calls and data flows\n- Model future bounded contexts using Domain-Driven Design\n- Create technology inventory (libraries, frameworks, protocols)\n- Document interface contracts for each module\n- Identify which teams own which modules for organizational alignment", "dependencies": []}, {"step_id": "S2", "title": "Data Dependency Analysis & Dual-Write Strategy", "description": "Untangle the 1.2TB database to support service independence without blocking progress.\n\n- Map all 350 tables to future service domains\n- Identify cross-service joins and stored procedures that span domains\n- Design per-service database schemas with minimal denormalization\n- Create data versioning framework to support rollback\n- Plan dual-write patterns: how old monolith and new services will sync during transition\n- Document eventual-consistency requirements and conflict resolution\n- Design data migration runbooks with clear rollback steps", "dependencies": ["S1"]}, {"step_id": "S3", "title": "Test Coverage Audit & Improvement Roadmap", "description": "Build confidence for service extraction by eliminating test blindness.\n\n- Audit current 25% test coverage by module\n- Identify coverage gaps in modules scheduled for early extraction\n- Establish target of 70%+ coverage for modules being extracted\n- Prioritize integration tests over unit tests given monolith complexity\n- Create quality gates: no service extraction below 60% module coverage\n- Plan for continuous improvement during extraction phases", "dependencies": ["S1"]}, {"step_id": "S4", "title": "Peak-Season Window Planning & Risk Framework", "description": "Protect January and July sales by scheduling extractions during safe windows.\n\n- Map annual peak periods: January sales (peak orders), July sales, plus any promotional events\n- Define 4-week freeze windows before/during peaks\n- Identify lowest-risk windows in each month for major changes\n- Create rollback procedures that execute in <30 minutes\n- Establish monitoring escalation for changes made near peak season\n- Document communication plan with business teams", "dependencies": ["S1"]}, {"step_id": "S5", "title": "Observability Foundation Setup", "description": "Instrument the system for real-time visibility during migration.\n\n- Deploy centralized logging (ELK, Splunk, or similar)\n- Set up metrics collection (Prometheus, Datadog, or similar)\n- Implement distributed tracing (Jaeger, Zipkin) for request flows across services\n- Create dashboards for: requests/sec, error rates, latency percentiles, database load\n- Define SLOs: order processing latency p99, checkout success rate, payment authorization speed\n- Set up alerts for SLO violations and anomalies", "dependencies": []}, {"step_id": "S6", "title": "Feature Flags, Containerization & API Gateway", "description": "Build the technical foundation for canary deployments and controlled traffic routing.\n\n- Implement feature flag system (LaunchDarkly, custom Spring Boot solution, etc.)\n- Containerize monolith and all new services (Docker)\n- Set up container orchestration (Kubernetes or similar) with service templates\n- Deploy API gateway (Kong, AWS ALB) with routing rules\n- Implement service-to-service authentication (mTLS, JWT)\n- Configure rate limiting and circuit breakers at gateway", "dependencies": []}, {"step_id": "S7", "title": "Deployment Pipeline & Automated Rollback", "description": "Enable safe, automated deployments with reliable rollback capability.\n\n- Implement CI/CD pipeline with automated testing gates\n- Set up blue-green deployment: run old and new versions in parallel, switch traffic atomically\n- Build canary deployment capability: route 5%→10%→50%→100% of traffic gradually\n- Automate rollback: trigger on error rate threshold, latency spike, or manual command\n- Create deployment runbooks for each service\n- All deployments must be independent; monolith keeps 2-week cycle until fully extracted", "dependencies": ["S6"]}, {"step_id": "S8", "title": "Test Coverage Improvement to 70%+", "description": "Close test gaps before extracting services to reduce rollback risk.\n\n- Implement integration tests for key flows: order creation, payment processing, inventory updates\n- Add contract tests between modules to catch breaking changes\n- Use mutation testing to verify test quality\n- Target 70%+ coverage for: pricing module, payment module, order management\n- Establish automated quality gates: coverage <70% blocks extraction of that service\n- Include tests for peak-load scenarios (40k→480k orders)", "dependencies": ["S3"]}, {"step_id": "S9", "title": "Search/Catalogue Service Extraction & Validation", "description": "Extract the first service: search is read-heavy, isolated, and low-risk.\n\n- Extract catalogue and search indexing logic from monolith\n- Build as independent Spring Boot service with own codebase/deployment\n- Create new database schema for catalogue (subset of 350 tables)\n- Implement dual-write: monolith writes to both old Lucene index and new service\n- Implement canary routing: API gateway sends 10% of search requests to new service, monitor latency and correctness\n- Validate results match between old and new service (checksums on result sets)\n- Gradually increase traffic: 10%→25%→50%→100%\n- Keep dual-write active for 2 weeks post-cutover for rollback safety", "dependencies": ["S7", "S8", "S3"]}, {"step_id": "S10", "title": "Event Bus & Service Mesh Infrastructure", "description": "Build async communication layer required for multi-service coordination.\n\n- Deploy message broker (Kafka recommended for ordering guarantees and peak load of 40k/sec)\n- Define domain events: OrderPlaced, PaymentAuthorized, InventoryReserved, etc.\n- Implement event schema versioning and compatibility\n- Set up service discovery (Consul, Kubernetes DNS)\n- Implement distributed configuration management\n- Create event publishing library for services to use\n- Document saga patterns for multi-step workflows\n- Test message broker under peak load (480k messages/day)", "dependencies": ["S9"]}, {"step_id": "S11", "title": "Inventory Service Extraction & Warehouse Sync", "description": "Extract inventory as second service: well-bounded, drives warehouse sync complexity.\n\n- Extract inventory logic and reservation system\n- Build inventory service with own database schema\n- Implement dual-write from monolith to both old and new inventory data\n- Preserve existing 15-minute warehouse file exchange, but now via service\n- Create inventory events: ReservationCreated, ReleaseRequested\n- Implement canary rollout: gradual traffic shift like search service\n- Test warehouse sync under peak load\n- Validate inventory consistency across monolith and new service before full cutover", "dependencies": ["S10"]}, {"step_id": "S12", "title": "Customer/Loyalty Service Extraction & Auth Refactoring", "description": "Extract customer accounts and loyalty: enables independent scaling of auth layer.\n\n- Extract customer account and loyalty program logic\n- Build customer service with own database schema\n- Separate authentication from monolith: implement API for token validation\n- Support multi-tenant loyalty rules (8 countries, country-specific points rules)\n- Implement canary rollout with real customer sessions\n- Create backwards-compatible customer APIs\n- Test account operations at peak concurrency (concurrent logins, loyalty point updates)\n- Plan for session management: ensure distributed sessions work across services", "dependencies": ["S10"]}, {"step_id": "S13", "title": "Saga Pattern Library & Order Orchestration Framework", "description": "Build the framework for managing distributed transactions across services.\n\n- Implement saga pattern library: choreography-based (event-driven) and orchestration-based patterns\n- Support compensating transactions: if payment fails, return inventory reservation\n- Handle timeouts and retries with exponential backoff\n- Implement idempotency keys to prevent duplicate charges on retries\n- Test saga execution under peak load and network failures\n- Document patterns for: order placement saga, payment saga, return saga\n- Create distributed tracing for saga flows", "dependencies": ["S10"]}, {"step_id": "S14", "title": "Pricing/Promotions Service Extraction (Phase 1: Extract As-Is)", "description": "Begin extraction of most complex module (200k LOC) without initial refactoring.\n\n- Extract pricing engine as-is with minimal refactoring to reduce initial risk\n- Preserve all country-specific rules and business logic\n- Build service boundary: accept pricing requests, return prices/promotions\n- Create feature tests that document all 200k LOC behavior\n- Map all promotion types to test scenarios\n- Test with real country/currency/language combinations\n- Implement as service behind same interface initially\n- Prepare for Phase 2 refactoring once stable in production", "dependencies": ["S13"]}, {"step_id": "S15", "title": "Pricing/Promotions Service Refinement (Phase 2: Rules Refactoring)", "description": "Gradually improve pricing service maintainability without breaking production.\n\n- Document the 200k LOC of complex rules in machine-readable format\n- Refactor rules engine into composable components\n- Build DSL for country-specific promotion rules\n- Decompose monolithic rule evaluation into smaller decision trees\n- Use feature flags to A/B test refactored rules vs old implementation\n- Optimize performance: reduce calculation time for promotions at checkout\n- Validate that refactored logic matches original behavior across all countries", "dependencies": ["S14"]}, {"step_id": "S16", "title": "Payment Service Extraction & Security Hardening", "description": "Extract payment processing with extreme rigor given PCI/regulatory requirements.\n\n- Separate payment logic from checkout: payment validation, three-provider integration\n- Build payment service with encrypted credential storage, no raw card data in logs\n- Implement fraud detection integration and decline handling\n- Audit for PCI-DSS compliance: minimal data exposure, encrypted transport\n- Implement E2E testing for all three payment provider scenarios\n- Load test payment service: 500+ payments/sec at peak\n- Implement idempotent payment requests: prevent double-charging on failures\n- Create detailed rollback procedures: how to fall back to direct monolith payment handling", "dependencies": ["S13"]}, {"step_id": "S17", "title": "Order Service Extraction & Event Stream", "description": "Extract order management: central service coordinating multiple workflows.\n\n- Extract order creation, status tracking, and management logic\n- Build order service with event stream: OrderCreated, PaymentAuthorized, InventoryReserved, OrderConfirmed\n- Support order querying by all 5 teams (inventory, fulfillment, customer service, etc.)\n- Implement order event sourcing for audit trail and replay capability\n- Create order state machine: validate state transitions\n- Test concurrent order processing at peak load (40k orders/day)", "dependencies": ["S13", "S16"]}, {"step_id": "S18", "title": "Checkout Service Composition via Saga", "description": "Compose checkout from independent payment, inventory, and order services using sagas.\n\n- Build checkout service that orchestrates: cart validation → pricing calculation → inventory reservation → payment authorization → order creation\n- Use saga pattern: if payment fails, release inventory reservation automatically\n- Implement distributed transaction semantics: all-or-nothing guarantee\n- Support three payment providers transparently\n- Test all failure scenarios: payment declines, inventory unavailable, warehouse system down\n- Implement timeout handling: what happens if inventory service is slow at peak\n- Validate checkout latency remains <5 seconds at peak load", "dependencies": ["S17"]}, {"step_id": "S19", "title": "Back-Office Integration with Service APIs", "description": "Update back-office (used by 300 staff) to coordinate across all services.\n\n- Create service aggregation endpoints: orders endpoint calls order service + payment service + inventory service\n- Update back-office UI to call new service APIs instead of monolith\n- Implement service discovery: handle service availability transparently\n- Create caching layer: reduce latency for frequently accessed data\n- Test with 300 concurrent staff users\n- Implement search across all orders/customers via service APIs\n- Add retry logic and timeouts to handle service failures gracefully", "dependencies": ["S18"]}, {"step_id": "S20", "title": "Storefront & Mobile App Refactoring", "description": "Update client applications to use new service architecture transparently.\n\n- Update server-rendered storefront templates to call service APIs\n- Update mobile app endpoints (already separate, now points to services via gateway)\n- Implement client-side caching: reduce latency impact of distributed calls\n- Maintain backwards compatibility: old clients must still work\n- Update API versioning: enable service changes without breaking clients\n- Implement request tracing: correlate user requests across services\n- Test storefront and mobile under peak load scenario (480k orders/day)", "dependencies": ["S19"]}, {"step_id": "S21", "title": "Legacy Database Deprecation & Data Migration", "description": "Safely decommission the monolith database once all services are independent.\n\n- Verify all data has been migrated to service-specific databases\n- Maintain 2-week read-only access to old database for emergency queries\n- Archive old database snapshots (regulatory requirement for order history)\n- Update backup/recovery procedures: now per-service instead of monolith\n- Verify no remaining cross-service joins depend on monolith schema\n- Document data mapping for future reference\n- Decommission old database infrastructure", "dependencies": ["S20"]}, {"step_id": "S22", "title": "Load Testing & Performance Optimization", "description": "Validate new architecture meets production capacity requirements.\n\n- Simulate peak load scenario: 480k orders/day (40k baseline × 12)\n- Test across 8 countries, 3 currencies, 4 languages simultaneously\n- Identify bottlenecks: service latency, database query performance, message broker throughput\n- Optimize hot paths: pricing calculations, search queries, payment processing\n- Test cache effectiveness: Lucene search response times, pricing cache hit rates\n- Validate database connection pools don't exhaust under peak load\n- Create load testing environment: realistic data, all 5 teams' concurrent usage", "dependencies": ["S21"]}, {"step_id": "S23", "title": "Documentation & Knowledge Transfer", "description": "Codify migration experience and new architecture for long-term success.\n\n- Document final service boundaries: APIs, responsibilities, data ownership\n- Create operational runbooks: how to deploy each service, how to handle common failures\n- Record architecture decision log: why services were split this way\n- Document data consistency model: eventual consistency patterns used\n- Create troubleshooting guides: common issues and resolutions\n- Train each team on their service and API contracts with other services\n- Record key decisions and trade-offs (e.g., why search is separate from catalogue, why pricing is monolithic within its service)", "dependencies": ["S22"]}, {"step_id": "S24", "title": "Production Stabilization & 30-Day Monitoring", "description": "Establish stable operation and prove architecture meets requirements.\n\n- Run 30-day monitoring period observing: error rates, latency, resource utilization\n- Establish performance baselines: P99 latency per service, throughput, error rates\n- Document SLO achievements: order processing speed, payment success rate, search latency\n- Create incident playbooks based on observed issues\n- Validate peak-load handling (Jan/July sales go normally through new architecture)\n- Establish team on-call procedures for service alerts\n- Plan for service scaling: autoscaling policies, capacity planning\n- Complete full rollback verification: ensure rollback to monolith is always possible", "dependencies": ["S23"]}], "estimated_complexity": "high", "success_metrics": "- All 8 services independently deployed and running in production with zero unplanned downtime during 12-month migration\n- Zero data inconsistencies between service-specific databases (validated by monthly reconciliation)\n- January and July peak seasons proceed with no degradation: 480k orders/day processed within 5-second checkout SLA\n- Test coverage increased from 25% to 70%+ for all extracted services\n- Every service deployment is fully automated; manual rollback procedures tested and <30 minutes to execute\n- Order processing latency (cart → confirmation) unchanged or improved: maintained under 5 seconds at peak load\n- All 5 teams deploying independently: no cross-team deployment coordination required after cutover\n- Pricing/promotions service successfully extracted with all 200k LOC of country-specific rules preserved and validated\n- Search latency improved or maintained despite architectural change\n- Inventory synchronization with warehouse continues reliably: no missed 15-minute sync cycles\n- Back-office operations for 300 staff members unaffected by migration; service aggregation endpoints maintain <500ms latency\n- Zero payment processing regressions: all three payment providers functioning, fraud detection active, PCI-DSS compliance maintained"}This proposal details a 15-step plan that establishes a Kubernetes platform and strangler fig facade before extracting any services. It leverages Change Data Capture and event streaming to decouple the database early in the process.
The plan concludes with team reorganization and monolith decommissioning after extracting core transactional flows. Delaying team reorganization to step 14 is a critical flaw that will cause organizational friction during the migration.
The plan produced
1. Mobilize Program and Define Target Architecture
Launch the migration program and define the target architecture. This step sets the foundation for all subsequent work.
Key activities:
- Establish a steering committee with business, architecture, and operations representatives.
- Conduct domain-driven design workshops to identify bounded contexts and service candidates.
- Define the target architecture: API gateway, service mesh, event-driven integration, and data ownership per service.
- Prioritize service extraction based on business value, risk, and coupling.
- Create architecture decision records (ADRs) and a service roadmap.
Output: a shared vision and prioritized backlog for the migration.
2. Build Platform Foundation for Independent Deployments (after 1)
Build the platform foundation required for independent deployments. This includes infrastructure, tooling, and golden paths.
Key activities:
- Provision a Kubernetes cluster with namespaces for each service.
- Set up CI/CD pipelines per service using GitLab CI or ArgoCD.
- Deploy an API gateway (e.g., Kong) and service mesh (e.g., Istio) for traffic management.
- Implement observability: centralized logging (ELK), metrics (Prometheus/Grafana), and tracing (Jaeger).
- Set up secrets management (Vault) and configuration management.
- Create golden path templates for new services to reduce boilerplate.
Output: a production-ready platform where teams can deploy services independently.
3. Implement Strangler Fig Facade and Monolith Instrumentation (after 2)
Implement the strangler fig facade and instrument the monolith. This allows incremental migration without disrupting users.
Key activities:
- Deploy the API gateway to route requests to the monolith or new services based on path or header.
- Modify the monolith to expose REST APIs for key domains (e.g., catalogue, customer).
- Implement the transactional outbox pattern to publish domain events from the monolith.
- Set up change data capture (CDC) from the monolith PostgreSQL to Kafka using Debezium.
- Introduce feature flags for routing and canary releases.
- Ensure all changes are backward compatible and can be rolled back.
Output: a facade that enables gradual traffic shifting and a data pipeline for synchronization.
4. Establish Continuous Delivery and Test Automation (after 1)
Establish continuous delivery and test automation to support safe, frequent deployments.
Key activities:
- Increase automated test coverage for critical monolith modules (target 60%).
- Implement consumer-driven contract testing (Pact) between monolith and new services.
- Set up automated regression test suites for end-to-end flows.
- Integrate tests into CI/CD pipelines with quality gates.
- Enable blue-green and canary deployments for both monolith and services.
Output: a reliable deployment pipeline that supports rollback and rapid feedback.
5. Extract Catalogue and Search Service (after 3, 4)
Extract the Catalogue and Search service. This is a read-heavy, low-coupling module, making it a good first candidate.
Key activities:
- Create a new Catalogue service with its own datastore (PostgreSQL for product data, Elasticsearch for search).
- Implement data synchronization from the monolith via CDC and events.
- Migrate read APIs for product listing and search to the new service via the gateway.
- Use feature flags to gradually shift traffic, with fallback to the monolith.
- Monitor performance and rollback if issues arise.
Output: an independently deployable Catalogue service serving a portion of traffic.
6. Extract Customer Accounts and Loyalty Service (after 3, 4, 5)
Extract the Customer Accounts and Loyalty service. This service manages profiles, addresses, and loyalty points.
Key activities:
- Create a new Customer service with its own database.
- Synchronize data from the monolith via events (customer created, updated).
- Migrate profile management and loyalty APIs to the new service.
- Keep authentication in the monolith initially to reduce risk.
- Redirect customer API calls to the new service gradually.
Output: an independently deployable Customer service with data ownership.
7. Extract Inventory Service (after 3, 4)
Extract the Inventory service. This service consumes the warehouse file feed directly and maintains real-time inventory.
Key activities:
- Create an Inventory service that reads the warehouse file feed (SFTP) and parses it.
- Publish inventory update events to Kafka.
- Migrate inventory queries from the monolith to the new service.
- Ensure the monolith and other services consume inventory events instead of querying the monolith DB.
Output: an independently deployable Inventory service with real-time updates.
8. Extract Returns Service (after 3, 4, 6)
Extract the Returns service. This module is relatively independent and can be extracted early.
Key activities:
- Create a Returns service with its own database.
- Consume order and customer events to validate returns.
- Migrate returns UI and APIs to the new service.
- Ensure integration with order management for refunds.
Output: an independently deployable Returns service.
9. Peak Season Readiness and Resilience Engineering (after 1)
Prepare for peak seasons and implement resilience engineering. This is critical to avoid downtime during January and July sales.
Key activities:
- Conduct load testing for 12x peak on new services and the monolith.
- Implement circuit breakers, bulkheads, rate limiting, and auto-scaling.
- Define change freeze periods: one month before and during January and July sales.
- Plan migration activities outside freeze windows.
- Run game days for failure scenarios and rollback drills.
Output: a system that can withstand peak loads and a schedule that protects peak seasons.
10. Extract Cart Service (after 3, 4, 7)
Extract the Cart service. The cart is a stateful component that requires careful handling.
Key activities:
- Create a Cart service with its own datastore (e.g., Redis or PostgreSQL) for session and cart items.
- Use the API gateway to route cart operations.
- Synchronize with the monolith via events for product and inventory validation.
- Ensure idempotency and session stickiness.
- Gradually migrate cart traffic using feature flags.
Output: an independently deployable Cart service.
11. Extract Order Management and Checkout Orchestration (after 6, 7, 9, 10)
Extract Order Management and Checkout Orchestration. This is the core transactional flow and requires a saga pattern.
Key activities:
- Create an Order service that orchestrates checkout using the saga pattern.
- Integrate with payment providers, inventory, pricing, and customer services.
- Migrate order placement and management APIs.
- Use events for order status updates.
- Ensure distributed transaction consistency and compensation logic.
Output: an independently deployable Order service handling the checkout flow.
12. Extract Pricing and Promotions Service (after 11)
Extract the Pricing and Promotions service. This is the most complex module with 200k lines of rules.
Key activities:
- Analyze and document the existing pricing rules and country-specific logic.
- Implement a new Pricing service, possibly using a rules engine (e.g., Drools).
- Migrate pricing calculations and promotions to the new service.
- Execute after other services are stable and outside peak seasons.
- Use extensive testing and canary releases.
Output: an independently deployable Pricing service with clear rules.
13. Database Decomposition and Stored Procedure Refactoring (after 3)
Decompose the database and refactor stored procedures. This is a cross-cutting concern that runs alongside service extraction.
Key activities:
- Start with logical separation: create schemas per service and move tables gradually.
- Refactor stored procedures into application code or move them to services.
- Eventually, give each service its own database instance.
- Use CDC and dual-write for data consistency during transition.
- Keep the monolith DB as source of truth until cutover.
Output: a decomposed database with clear data ownership.
14. Reorganize Teams for Independent Deployment (after 1, 2)
Reorganize teams for independent deployment. This step enables long-term autonomy.
Key activities:
- Reorganize teams around services (stream-aligned teams).
- Give each team ownership of its service's repository, CI/CD, and on-call.
- Implement an internal developer platform for self-service deployments.
- Establish service level objectives (SLOs) and error budgets.
Output: autonomous teams that can deploy independently.
15. Post-Migration Optimization and Monolith Decommissioning (after 12)
Optimize after migration and decommission the monolith. This step wraps up the migration.
Key activities:
- After each service extraction, remove dead code from the monolith.
- Gradually reduce the monolith to a smaller core (e.g., back-office).
- Plan eventual decommissioning of monolith components.
- Document learnings and update architecture.
Output: a leaner monolith and a fully service-oriented architecture.
- 100% of planned service extractions completed within 12 months.
- Zero unplanned downtime during January and July peak sales.
- All new services independently deployable with <5 minute lead time.
- 100% of deployments rollback-able within 5 minutes.
- 80% of traffic served by new services by end of 12 months.
- Test coverage increased to 60% for critical modules.
- Deployment frequency increased from bi-weekly to daily.
- Mean time to recovery (MTTR) < 30 minutes.
- Change failure rate < 15%.
- All stored procedures refactored or migrated to services.
- Database decomposed into 5+ independent databases.
- Peak load capacity sustained at 12x with <1% error rate.
[SYSTEM]
You are an expert assistant in complex project planning.
Your task is to generate a detailed and structured action plan to reach the main objective in the most professional and most detailed way, no matter how much work or steps will be needed to perform.
Use your internal reasoning processes to think deeply about the problem and create the most comprehensive plan possible.
Take as much time and space as you need to think through all aspects of the problem.
After your thorough analysis, answer with the plan in the requested structure.
Every text field you write will be read by a busy person, so write for them: short sentences, one idea each, in short paragraphs. Text fields accept Markdown: separate paragraphs with a blank line, use a bullet list when you enumerate things and plain paragraphs when you explain or argue, and bold at most one key phrase per paragraph. A text of more than three sentences must be split into paragraphs; never deliver a single unbroken block of text.
[HUMAN]
Main Objective: "A mid-size European fashion retailer runs its e-commerce on a 10-year-old monolith: Java 8 / Spring, about 2 million lines, one PostgreSQL database of 1.2 TB with 350 tables and heavy use of stored procedures and cross-module joins. It serves 8 countries, 3 currencies and 4 languages, with about 40,000 orders a day and peaks of 12x during sales. The monolith contains: the storefront (server-rendered, plus a separate mobile app hitting the same endpoints), catalogue and search (a Lucene index rebuilt nightly), pricing and promotions (the most complex module, 200,000 lines, with country-specific rules nobody fully understands), cart and checkout with three payment providers, order management, inventory synchronised every 15 minutes with the warehouse system via file exchange, customer accounts and loyalty, returns, and a back-office used by 300 staff. Deployments happen every two weeks as a single artefact with a 30-minute maintenance window; test coverage is 25% and mostly unit tests. Five teams of 8 developers, each organised around a business area but all committing to the same repository.
Plan the migration to independently deployable services over 12 months with no feature freeze, no unplanned downtime and the ability to roll back every step, preserving the peak-season capacity (sales in January and July must not be put at risk)."
Generate an initial, detailed, and well-structured plan proposal.
The plan has these parts:
- "steps": the list of steps, each with "step_id" (a short label unique within this proposal, such as S1, S2, S3), "title" (a short, descriptive title), "description" (what the step does and how, in Markdown: a short opening paragraph and then, if there are several concrete things to say, a bullet list) and "dependencies" (the step_ids of the other steps of THIS proposal that must be completed first; empty if none).
- "estimated_complexity": "low", "medium" or "high".
- "success_metrics": clear and measurable success metrics, one per line as a bullet list.
Think deeply about the problem, considering all aspects and implications. Develop a comprehensive understanding of what needs to be done to achieve the objective, then produce the plan.
Answer with a single JSON object, and nothing else, that conforms to this JSON schema:
{"description": "The structure every proposing agent must answer with.", "properties": {"steps": {"items": {"description": "One step of a proposed plan. Dependencies are step_ids of the same proposal.", "properties": {"step_id": {"title": "Step Id", "type": "string"}, "title": {"title": "Title", "type": "string"}, "description": {"title": "Description", "type": "string"}, "dependencies": {"items": {"type": "string"}, "title": "Dependencies", "type": "array"}}, "required": ["step_id", "title", "description", "dependencies"], "title": "Step", "type": "object", "additionalProperties": false}, "title": "Steps", "type": "array"}, "estimated_complexity": {"title": "Estimated Complexity", "type": "string"}, "success_metrics": {"title": "Success Metrics", "type": "string"}}, "required": ["steps", "estimated_complexity", "success_metrics"], "title": "ProposalContent", "type": "object", "additionalProperties": false}
{"steps": [{"step_id": "S1", "title": "Mobilize Program and Define Target Architecture", "description": "Launch the migration program and define the target architecture. This step sets the foundation for all subsequent work.\n\nKey activities:\n\n- Establish a steering committee with business, architecture, and operations representatives.\n- Conduct domain-driven design workshops to identify bounded contexts and service candidates.\n- Define the target architecture: API gateway, service mesh, event-driven integration, and data ownership per service.\n- Prioritize service extraction based on business value, risk, and coupling.\n- Create architecture decision records (ADRs) and a service roadmap.\n\nOutput: a shared vision and prioritized backlog for the migration.", "dependencies": []}, {"step_id": "S2", "title": "Build Platform Foundation for Independent Deployments", "description": "Build the platform foundation required for independent deployments. This includes infrastructure, tooling, and golden paths.\n\nKey activities:\n\n- Provision a Kubernetes cluster with namespaces for each service.\n- Set up CI/CD pipelines per service using GitLab CI or ArgoCD.\n- Deploy an API gateway (e.g., Kong) and service mesh (e.g., Istio) for traffic management.\n- Implement observability: centralized logging (ELK), metrics (Prometheus/Grafana), and tracing (Jaeger).\n- Set up secrets management (Vault) and configuration management.\n- Create golden path templates for new services to reduce boilerplate.\n\nOutput: a production-ready platform where teams can deploy services independently.", "dependencies": ["S1"]}, {"step_id": "S3", "title": "Implement Strangler Fig Facade and Monolith Instrumentation", "description": "Implement the strangler fig facade and instrument the monolith. This allows incremental migration without disrupting users.\n\nKey activities:\n\n- Deploy the API gateway to route requests to the monolith or new services based on path or header.\n- Modify the monolith to expose REST APIs for key domains (e.g., catalogue, customer).\n- Implement the transactional outbox pattern to publish domain events from the monolith.\n- Set up change data capture (CDC) from the monolith PostgreSQL to Kafka using Debezium.\n- Introduce feature flags for routing and canary releases.\n- Ensure all changes are backward compatible and can be rolled back.\n\nOutput: a facade that enables gradual traffic shifting and a data pipeline for synchronization.", "dependencies": ["S2"]}, {"step_id": "S4", "title": "Establish Continuous Delivery and Test Automation", "description": "Establish continuous delivery and test automation to support safe, frequent deployments.\n\nKey activities:\n\n- Increase automated test coverage for critical monolith modules (target 60%).\n- Implement consumer-driven contract testing (Pact) between monolith and new services.\n- Set up automated regression test suites for end-to-end flows.\n- Integrate tests into CI/CD pipelines with quality gates.\n- Enable blue-green and canary deployments for both monolith and services.\n\nOutput: a reliable deployment pipeline that supports rollback and rapid feedback.", "dependencies": ["S1"]}, {"step_id": "S5", "title": "Extract Catalogue and Search Service", "description": "Extract the Catalogue and Search service. This is a read-heavy, low-coupling module, making it a good first candidate.\n\nKey activities:\n\n- Create a new Catalogue service with its own datastore (PostgreSQL for product data, Elasticsearch for search).\n- Implement data synchronization from the monolith via CDC and events.\n- Migrate read APIs for product listing and search to the new service via the gateway.\n- Use feature flags to gradually shift traffic, with fallback to the monolith.\n- Monitor performance and rollback if issues arise.\n\nOutput: an independently deployable Catalogue service serving a portion of traffic.", "dependencies": ["S3", "S4"]}, {"step_id": "S6", "title": "Extract Customer Accounts and Loyalty Service", "description": "Extract the Customer Accounts and Loyalty service. This service manages profiles, addresses, and loyalty points.\n\nKey activities:\n\n- Create a new Customer service with its own database.\n- Synchronize data from the monolith via events (customer created, updated).\n- Migrate profile management and loyalty APIs to the new service.\n- Keep authentication in the monolith initially to reduce risk.\n- Redirect customer API calls to the new service gradually.\n\nOutput: an independently deployable Customer service with data ownership.", "dependencies": ["S3", "S4", "S5"]}, {"step_id": "S7", "title": "Extract Inventory Service", "description": "Extract the Inventory service. This service consumes the warehouse file feed directly and maintains real-time inventory.\n\nKey activities:\n\n- Create an Inventory service that reads the warehouse file feed (SFTP) and parses it.\n- Publish inventory update events to Kafka.\n- Migrate inventory queries from the monolith to the new service.\n- Ensure the monolith and other services consume inventory events instead of querying the monolith DB.\n\nOutput: an independently deployable Inventory service with real-time updates.", "dependencies": ["S3", "S4"]}, {"step_id": "S8", "title": "Extract Returns Service", "description": "Extract the Returns service. This module is relatively independent and can be extracted early.\n\nKey activities:\n\n- Create a Returns service with its own database.\n- Consume order and customer events to validate returns.\n- Migrate returns UI and APIs to the new service.\n- Ensure integration with order management for refunds.\n\nOutput: an independently deployable Returns service.", "dependencies": ["S3", "S4", "S6"]}, {"step_id": "S9", "title": "Peak Season Readiness and Resilience Engineering", "description": "Prepare for peak seasons and implement resilience engineering. This is critical to avoid downtime during January and July sales.\n\nKey activities:\n\n- Conduct load testing for 12x peak on new services and the monolith.\n- Implement circuit breakers, bulkheads, rate limiting, and auto-scaling.\n- Define change freeze periods: one month before and during January and July sales.\n- Plan migration activities outside freeze windows.\n- Run game days for failure scenarios and rollback drills.\n\nOutput: a system that can withstand peak loads and a schedule that protects peak seasons.", "dependencies": ["S1"]}, {"step_id": "S10", "title": "Extract Cart Service", "description": "Extract the Cart service. The cart is a stateful component that requires careful handling.\n\nKey activities:\n\n- Create a Cart service with its own datastore (e.g., Redis or PostgreSQL) for session and cart items.\n- Use the API gateway to route cart operations.\n- Synchronize with the monolith via events for product and inventory validation.\n- Ensure idempotency and session stickiness.\n- Gradually migrate cart traffic using feature flags.\n\nOutput: an independently deployable Cart service.", "dependencies": ["S3", "S4", "S7"]}, {"step_id": "S11", "title": "Extract Order Management and Checkout Orchestration", "description": "Extract Order Management and Checkout Orchestration. This is the core transactional flow and requires a saga pattern.\n\nKey activities:\n\n- Create an Order service that orchestrates checkout using the saga pattern.\n- Integrate with payment providers, inventory, pricing, and customer services.\n- Migrate order placement and management APIs.\n- Use events for order status updates.\n- Ensure distributed transaction consistency and compensation logic.\n\nOutput: an independently deployable Order service handling the checkout flow.", "dependencies": ["S10", "S6", "S7", "S9"]}, {"step_id": "S12", "title": "Extract Pricing and Promotions Service", "description": "Extract the Pricing and Promotions service. This is the most complex module with 200k lines of rules.\n\nKey activities:\n\n- Analyze and document the existing pricing rules and country-specific logic.\n- Implement a new Pricing service, possibly using a rules engine (e.g., Drools).\n- Migrate pricing calculations and promotions to the new service.\n- Execute after other services are stable and outside peak seasons.\n- Use extensive testing and canary releases.\n\nOutput: an independently deployable Pricing service with clear rules.", "dependencies": ["S11"]}, {"step_id": "S13", "title": "Database Decomposition and Stored Procedure Refactoring", "description": "Decompose the database and refactor stored procedures. This is a cross-cutting concern that runs alongside service extraction.\n\nKey activities:\n\n- Start with logical separation: create schemas per service and move tables gradually.\n- Refactor stored procedures into application code or move them to services.\n- Eventually, give each service its own database instance.\n- Use CDC and dual-write for data consistency during transition.\n- Keep the monolith DB as source of truth until cutover.\n\nOutput: a decomposed database with clear data ownership.", "dependencies": ["S3"]}, {"step_id": "S14", "title": "Reorganize Teams for Independent Deployment", "description": "Reorganize teams for independent deployment. This step enables long-term autonomy.\n\nKey activities:\n\n- Reorganize teams around services (stream-aligned teams).\n- Give each team ownership of its service's repository, CI/CD, and on-call.\n- Implement an internal developer platform for self-service deployments.\n- Establish service level objectives (SLOs) and error budgets.\n\nOutput: autonomous teams that can deploy independently.", "dependencies": ["S1", "S2"]}, {"step_id": "S15", "title": "Post-Migration Optimization and Monolith Decommissioning", "description": "Optimize after migration and decommission the monolith. This step wraps up the migration.\n\nKey activities:\n\n- After each service extraction, remove dead code from the monolith.\n- Gradually reduce the monolith to a smaller core (e.g., back-office).\n- Plan eventual decommissioning of monolith components.\n- Document learnings and update architecture.\n\nOutput: a leaner monolith and a fully service-oriented architecture.", "dependencies": ["S12"]}], "estimated_complexity": "high", "success_metrics": "- 100% of planned service extractions completed within 12 months.\n- Zero unplanned downtime during January and July peak sales.\n- All new services independently deployable with <5 minute lead time.\n- 100% of deployments rollback-able within 5 minutes.\n- 80% of traffic served by new services by end of 12 months.\n- Test coverage increased to 60% for critical modules.\n- Deployment frequency increased from bi-weekly to daily.\n- Mean time to recovery (MTTR) < 30 minutes.\n- Change failure rate < 15%.\n- All stored procedures refactored or migrated to services.\n- Database decomposed into 5+ independent databases.\n- Peak load capacity sustained at 12x with <1% error rate."}This strategy uses a 10-step framework centered on event storming and a robust data platform utilizing the Outbox pattern. It treats the complex Pricing module as a black box wrapped in characterization tests to avoid rewriting unknown rules.
The extraction order prioritizes read-only pilots before moving to stateful domains like Cart and Checkout. While pragmatic, the 10-step high-level approach lacks the granular dependency mapping required for a 1.2 TB database.
The plan produced
1. Foundation: Infrastructure, Observability, and Safety Net
Before extracting any service, the team must build the 'operating system' for distributed applications. This step focuses on enabling independent deployment and providing real-time visibility into the legacy monolith. The goal is to create a safety net that makes subsequent refactoring steps low-risk and reversible.
- CI/CD Pipeline: Implement a dual-track pipeline. The existing monolith gets a 'speedy' pipeline for hotfixes, while a new pipeline infrastructure is set up (e.g., Kubernetes/ECS) ready for independent service deployment.
- Observability Suite: Deploy centralized logging (ELK/Loki), metrics (Prometheus/Grafana), and crucially, Distributed Tracing (Jaeger/Zipkin). Even within the monolith, we must map request flows to identify coupling.
- Service Mesh / API Gateway: Install an API Gateway (e.g., Kong, Nginx ingress) in front of the monolith. This is the 'strangler fig' entry point. All traffic must flow through here. We will use it to route traffic to new services or fallback to the monolith.
- Feature Flags: Integrate a feature management system (e.g., LaunchDarkly, Unleash) to decouple deployment from release. This allows us to deploy code that is inactive and test it behind flags.
2. Domain Analysis and Boundary Definition (Strangler Pattern) (after 1)
You cannot extract a service without knowing the domain. With 2M lines and 'unknown' pricing logic, this step is about mapping the terrain. We aim to identify low-risk, high-cohesion boundaries for the first extractions and mark the 'danger zones' (Pricing) for later.
- Event Storming: Run workshops with the five teams to map business flows (e.g., 'Checkout', 'Return') and identify command/event boundaries.
- Code Hotspot Analysis: Use static analysis tools (e.g., SonarQube, CodeScene) to find files changed together (logical coupling) and complex methods.
- Dependency Matrix: Create a matrix showing which database tables are accessed by which application modules. This is critical for the database refactoring later.
- Service Extraction Plan: Finalize the order of extraction. Recommended: Search/Catalogue (read-heavy, low transactional consistency risk) or Inventory (async, distinct boundary). Avoid 'Pricing' initially due to complexity and 'Checkout' until foundational identity is stable.
3. Data Platform Strategy: Outbox Pattern and CDC (after 2)
The 1.2TB PostgreSQL DB with stored procedures is the 'database of doom' for migration. We must stop using cross-module SQL joins. This step introduces a data change capture layer to allow services to communicate via events rather than DB writes.
- Database Isolation: Begin identifying tables exclusive to the chosen first domain (e.g., Catalogue tables). Grant strict read-only access to other modules if possible, or refactor code to remove cross-table joins.
- Change Data Capture (CDC): Deploy a tool (e.g., Debezium or Kafka Connect) to stream PostgreSQL WAL logs to a message broker (Kafka/Pulsar). This creates a stream of data changes that can be consumed by other services.
- Transaction Outbox: Refactor the monolith code to use an 'Outbox Pattern' for domain events. Instead of just writing to the DB, it also writes a message to an 'Outbox' table in the same transaction. A relay process moves this to Kafka. This ensures 'at least once' delivery and keeps the monolith's transactional integrity while enabling async communication.
4. Extraction of First Service (The 'Read-Only' Pilot) (after 1, 3)
To learn safely, we extract a 'read-only' service with no transactional complexity. The Product Catalogue/Search is the best candidate. It is currently Lucene-based, rebuilt nightly. We will move to real-time indexing to improve product freshness.
- Build the Catalogue Service: Create a new microservice that owns the Catalogue database tables. It exposes gRPC/REST endpoints for fetching products.
- Real-time Sync: The new service subscribes to the CDC events for product changes (from S3). It updates its internal Lucene/Opensearch index in real-time. This eliminates the nightly rebuild and provides immediate search visibility.
- Dual Read Path: The monolith code for 'Search' is modified to check a feature flag. If enabled, it calls the new Catalogue Service; otherwise, it uses the old internal Lucene logic.
- Shadow Traffic: Use the API Gateway to duplicate live traffic. Send requests to both the monolith and the new service. Compare the responses. Only when error rates are 0% do we flip the feature flag for production traffic.
5. Extraction of Identity and Customer Accounts (after 4)
Next, we extract the Customer Account domain. This serves both the storefront and the mobile app. This is a write-heavy domain, requiring careful transaction handling with the legacy monolith during the transition.
- Service Implementation: Implement the 'Customer Service' (JWT generation, profile management, authentication). It owns its own database schema (User, Address).
- Sync with Legacy: The service publishes 'UserUpdated' and 'UserCreated' events via Outbox/CDC. The monolith listens to these events to keep its local copy of user data synchronized.
- Strangler Endpoint: The API Gateway routes '/api/login', '/api/account' traffic directly to the new service. The monolith stops handling these requests. Front-end applications must be updated to handle the new response format (versioning).
- Database Decoupling: Over time, remove read access to the monolith's user table for all other domains, forcing them to use the Identity service.
6. Extraction of Inventory Synchronization (after 5)
Inventory is currently updated every 15 minutes via files. This is a bottleneck. We will extract this into a service that integrates directly with the Warehouse Management System (WMS).
- Inventory Service: Build a service that consumes warehouse data feeds (replacing the file drop). It updates a centralized stock level view.
- Event Publishing: When stock levels change, publish
StockLevelChangedevents to Kafka. - Monolith Integration: Refactor the Cart/Checkout code in the monolith to listen to these events to maintain a local cached view of inventory or to check stock via an API call rather than a SQL join. This removes the 15-minute latency.
- Consistency Model: Since inventory is high-concurrency, design a reservation system (Saga) for this service to prepare for the future extraction of Checkout.
7. The 'Black Box' Strategy for Pricing and Promotions (after 6)
The pricing module (200k lines, unknown rules) cannot be rewritten safely from scratch. We treat it as a 'legacy core'. We will wrap it in a service but keep the internal logic untouched in the monolith initially, or isolate it.
- Characterization Tests: Write massive integration tests that record the input/output of the pricing module for all 8 countries and 3 currencies. This creates a 'golden master'.
- Decouple Dependencies: Refactor the pricing code to rely only on 'Customer', 'Product', and 'Inventory' data fetched via interfaces, not direct DB calls. This prepares it for extraction.
- Extract as 'Black Box': Wrap the existing pricing logic into a new
Pricing Service. Move the 200k lines of code into this project. It calls a dedicated read-replica database of the pricing tables. This service does not communicate with others directly but is called by the 'Cart' service. - Validation: Run 'shadow mode' traffic against this new service to ensure it matches the golden master before routing any production traffic.
8. Orchestration Layer: Cart and Checkout (The Saga) (after 7)
Checkout is the highest risk. It requires distributed transaction management. We will implement the Cart as a service and the Checkout process as an orchestrator using Sagas.
- Cart Service: Extract cart logic into its own stateless/stateful service (Redis-backed). This decouples the browsing experience from the order processing.
- Checkout Orchestrator: Build a new 'Order Service' that does not do the work itself but coordinates the process. When a checkout starts, the Order Service begins a Saga.
- Saga Steps: 1. Validate Pricing (via Pricing Service), 2. Reserve Inventory (via Inventory Service), 3. Authorize Payment (via Payment Service), 4. Create Order Record. If step 3 fails, step 1/2 must be compensated (rollback).
- Idempotency: Ensure all services in the saga accept Idempotency Keys to prevent double-charging or double-stock deduction.
9. Extraction of Payments and Order Management (after 8)
Complete the order lifecycle. Move payment integration and order status tracking out of the monolith.
- Payment Gateway: Extract the integration with the 3 providers into a
Payment Service. This service handles webhooks, refunds, and tokenization (PCI scope reduction). - Order Management System (OMS): Move the database table
ordersand associated history into a newOrder Service. It consumes the events generated by the Checkout Saga. - Back-office Migration: The back-office (300 staff) is likely server-rendered. Refactor these screens to consume the new
Order ServiceAPIs. Remove the back-office's direct SQL access to the orders table. This is crucial for reducing load on the monolith DB.
- Payment Gateway: Extract the integration with the 3 providers into a
10. Legacy Cleanup and Peak Season Preparation (after 9)
The monolith should now be a 'hollowed-out' shell (mostly just the legacy pricing rules inside a service or a 'legacy' module). We prepare for the peak sales in Jan/July.
- Database Downsizing: Detach the schema ownership. The monolith should ideally only connect to a 'read-only' replica for historical data or a small remnant DB.
- Performance Tuning: The new architecture is now the single point of failure. Optimize the message broker (Kafka) and API Gateway for 12x traffic.
- Chaos Engineering: Run game-days testing resilience. Kill a service (e.g., Search) and ensure the storefront degrades gracefully (shows empty search results but allows cart access).
- Final Monolith Decommission: Identify the remaining monolith code. Delete it. If it's just a 'legacy gateway', replace it with pure API routing. The 'Monolith' label should now refer only to the Pricing Service or similar, not a single deployable unit.
- Zero Downtime: Achieve 100% availability of the e-commerce platform throughout the 12 months, including planned maintenance windows.
- Deployment Independence: New services can be deployed independently; no code commit forces a full 30-minute monolith downtime. Time-to-deploy for a new service < 5 minutes.
- Database Decoupling: Eliminate cross-service SQL joins. The monolith database write load decreases by 90%.
- Peak Capacity: System handles 12x traffic load (approx. 480k orders/day) with < 200ms latency at P95 during load tests.
- Search Latency: Product availability reflected in search results within < 30 seconds of inventory update (replacing nightly rebuild).
- Pricing Stability: 0% deviation in price calculation results between the new architecture and the legacy 'golden master' characterization tests.
[SYSTEM] You are an expert assistant in complex project planning. Your task is to generate a detailed and structured action plan to reach the main objective in the most professional and most detailed way, no matter how much work or steps will be needed to perform. Use your internal reasoning processes to think deeply about the problem and create the most comprehensive plan possible. Take as much time and space as you need to think through all aspects of the problem. After your thorough analysis, answer with the plan in the requested structure. Every text field you write will be read by a busy person, so write for them: short sentences, one idea each, in short paragraphs. Text fields accept Markdown: separate paragraphs with a blank line, use a bullet list when you enumerate things and plain paragraphs when you explain or argue, and bold at most one key phrase per paragraph. A text of more than three sentences must be split into paragraphs; never deliver a single unbroken block of text. [HUMAN] Main Objective: "A mid-size European fashion retailer runs its e-commerce on a 10-year-old monolith: Java 8 / Spring, about 2 million lines, one PostgreSQL database of 1.2 TB with 350 tables and heavy use of stored procedures and cross-module joins. It serves 8 countries, 3 currencies and 4 languages, with about 40,000 orders a day and peaks of 12x during sales. The monolith contains: the storefront (server-rendered, plus a separate mobile app hitting the same endpoints), catalogue and search (a Lucene index rebuilt nightly), pricing and promotions (the most complex module, 200,000 lines, with country-specific rules nobody fully understands), cart and checkout with three payment providers, order management, inventory synchronised every 15 minutes with the warehouse system via file exchange, customer accounts and loyalty, returns, and a back-office used by 300 staff. Deployments happen every two weeks as a single artefact with a 30-minute maintenance window; test coverage is 25% and mostly unit tests. Five teams of 8 developers, each organised around a business area but all committing to the same repository. Plan the migration to independently deployable services over 12 months with no feature freeze, no unplanned downtime and the ability to roll back every step, preserving the peak-season capacity (sales in January and July must not be put at risk)." Generate an initial, detailed, and well-structured plan proposal. The plan has these parts: - "steps": the list of steps, each with "step_id" (a short label unique within this proposal, such as S1, S2, S3), "title" (a short, descriptive title), "description" (what the step does and how, in Markdown: a short opening paragraph and then, if there are several concrete things to say, a bullet list) and "dependencies" (the step_ids of the other steps of THIS proposal that must be completed first; empty if none). - "estimated_complexity": "low", "medium" or "high". - "success_metrics": clear and measurable success metrics, one per line as a bullet list. Think deeply about the problem, considering all aspects and implications. Develop a comprehensive understanding of what needs to be done to achieve the objective, then produce the plan.
{"steps": [{"step_id": "S1", "title": "Foundation: Infrastructure, Observability, and Safety Net", "description": "Before extracting any service, the team must build the 'operating system' for distributed applications. This step focuses on enabling independent deployment and providing real-time visibility into the legacy monolith. The goal is to create a safety net that makes subsequent refactoring steps low-risk and reversible.\n\n* **CI/CD Pipeline**: Implement a dual-track pipeline. The existing monolith gets a 'speedy' pipeline for hotfixes, while a new pipeline infrastructure is set up (e.g., Kubernetes/ECS) ready for independent service deployment.\n* **Observability Suite**: Deploy centralized logging (ELK/Loki), metrics (Prometheus/Grafana), and crucially, **Distributed Tracing** (Jaeger/Zipkin). Even within the monolith, we must map request flows to identify coupling.\n* **Service Mesh / API Gateway**: Install an API Gateway (e.g., Kong, Nginx ingress) in front of the monolith. This is the 'strangler fig' entry point. All traffic must flow through here. We will use it to route traffic to new services or fallback to the monolith.\n* **Feature Flags**: Integrate a feature management system (e.g., LaunchDarkly, Unleash) to decouple deployment from release. This allows us to deploy code that is inactive and test it behind flags.", "dependencies": []}, {"step_id": "S2", "title": "Domain Analysis and Boundary Definition (Strangler Pattern)", "description": "You cannot extract a service without knowing the domain. With 2M lines and 'unknown' pricing logic, this step is about mapping the terrain. We aim to identify low-risk, high-cohesion boundaries for the first extractions and mark the 'danger zones' (Pricing) for later.\n\n* **Event Storming**: Run workshops with the five teams to map business flows (e.g., 'Checkout', 'Return') and identify command/event boundaries.\n* **Code Hotspot Analysis**: Use static analysis tools (e.g., SonarQube, CodeScene) to find files changed together (logical coupling) and complex methods.\n* **Dependency Matrix**: Create a matrix showing which database tables are accessed by which application modules. This is critical for the database refactoring later.\n* **Service Extraction Plan**: Finalize the order of extraction. Recommended: **Search/Catalogue** (read-heavy, low transactional consistency risk) or **Inventory** (async, distinct boundary). Avoid 'Pricing' initially due to complexity and 'Checkout' until foundational identity is stable.", "dependencies": ["S1"]}, {"step_id": "S3", "title": "Data Platform Strategy: Outbox Pattern and CDC", "description": "The 1.2TB PostgreSQL DB with stored procedures is the 'database of doom' for migration. We must stop using cross-module SQL joins. This step introduces a data change capture layer to allow services to communicate via events rather than DB writes.\n\n* **Database Isolation**: Begin identifying tables exclusive to the chosen first domain (e.g., Catalogue tables). Grant strict read-only access to other modules if possible, or refactor code to remove cross-table joins.\n* **Change Data Capture (CDC)**: Deploy a tool (e.g., Debezium or Kafka Connect) to stream PostgreSQL WAL logs to a message broker (Kafka/Pulsar). This creates a stream of data changes that can be consumed by other services.\n* **Transaction Outbox**: Refactor the monolith code to use an 'Outbox Pattern' for domain events. Instead of just writing to the DB, it also writes a message to an 'Outbox' table in the same transaction. A relay process moves this to Kafka. This ensures 'at least once' delivery and keeps the monolith's transactional integrity while enabling async communication.", "dependencies": ["S2"]}, {"step_id": "S4", "title": "Extraction of First Service (The 'Read-Only' Pilot)", "description": "To learn safely, we extract a 'read-only' service with no transactional complexity. The **Product Catalogue/Search** is the best candidate. It is currently Lucene-based, rebuilt nightly. We will move to real-time indexing to improve product freshness.\n\n* **Build the Catalogue Service**: Create a new microservice that owns the Catalogue database tables. It exposes gRPC/REST endpoints for fetching products.\n* **Real-time Sync**: The new service subscribes to the CDC events for product changes (from S3). It updates its internal Lucene/Opensearch index in real-time. This eliminates the nightly rebuild and provides immediate search visibility.\n* **Dual Read Path**: The monolith code for 'Search' is modified to check a feature flag. If enabled, it calls the new Catalogue Service; otherwise, it uses the old internal Lucene logic.\n* **Shadow Traffic**: Use the API Gateway to duplicate live traffic. Send requests to both the monolith and the new service. Compare the responses. Only when error rates are 0% do we flip the feature flag for production traffic.", "dependencies": ["S1", "S3"]}, {"step_id": "S5", "title": "Extraction of Identity and Customer Accounts", "description": "Next, we extract the **Customer Account** domain. This serves both the storefront and the mobile app. This is a write-heavy domain, requiring careful transaction handling with the legacy monolith during the transition.\n\n* **Service Implementation**: Implement the 'Customer Service' (JWT generation, profile management, authentication). It owns its own database schema (User, Address).\n* **Sync with Legacy**: The service publishes 'UserUpdated' and 'UserCreated' events via Outbox/CDC. The monolith listens to these events to keep its local copy of user data synchronized.\n* **Strangler Endpoint**: The API Gateway routes '/api/login', '/api/account' traffic directly to the new service. The monolith stops handling these requests. Front-end applications must be updated to handle the new response format (versioning).\n* **Database Decoupling**: Over time, remove read access to the monolith's user table for all other domains, forcing them to use the Identity service.", "dependencies": ["S4"]}, {"step_id": "S6", "title": "Extraction of Inventory Synchronization", "description": "Inventory is currently updated every 15 minutes via files. This is a bottleneck. We will extract this into a service that integrates directly with the Warehouse Management System (WMS).\n\n* **Inventory Service**: Build a service that consumes warehouse data feeds (replacing the file drop). It updates a centralized stock level view.\n* **Event Publishing**: When stock levels change, publish `StockLevelChanged` events to Kafka.\n* **Monolith Integration**: Refactor the Cart/Checkout code in the monolith to listen to these events to maintain a local cached view of inventory or to check stock via an API call rather than a SQL join. This removes the 15-minute latency.\n* **Consistency Model**: Since inventory is high-concurrency, design a reservation system (Saga) for this service to prepare for the future extraction of Checkout.", "dependencies": ["S5"]}, {"step_id": "S7", "title": "The 'Black Box' Strategy for Pricing and Promotions", "description": "The pricing module (200k lines, unknown rules) cannot be rewritten safely from scratch. We treat it as a 'legacy core'. We will wrap it in a service but keep the internal logic untouched in the monolith initially, or isolate it.\n\n* **Characterization Tests**: Write massive integration tests that record the input/output of the pricing module for all 8 countries and 3 currencies. This creates a 'golden master'.\n* **Decouple Dependencies**: Refactor the pricing code to rely only on 'Customer', 'Product', and 'Inventory' data fetched via interfaces, not direct DB calls. This prepares it for extraction.\n* **Extract as 'Black Box'**: Wrap the existing pricing logic into a new `Pricing Service`. Move the 200k lines of code into this project. It calls a dedicated read-replica database of the pricing tables. This service does not communicate with others directly but is called by the 'Cart' service.\n* **Validation**: Run 'shadow mode' traffic against this new service to ensure it matches the golden master before routing any production traffic.", "dependencies": ["S6"]}, {"step_id": "S8", "title": "Orchestration Layer: Cart and Checkout (The Saga)", "description": "Checkout is the highest risk. It requires distributed transaction management. We will implement the Cart as a service and the Checkout process as an orchestrator using Sagas.\n\n* **Cart Service**: Extract cart logic into its own stateless/stateful service (Redis-backed). This decouples the browsing experience from the order processing.\n* **Checkout Orchestrator**: Build a new 'Order Service' that does not do the work itself but coordinates the process. When a checkout starts, the Order Service begins a **Saga**.\n* **Saga Steps**: 1. Validate Pricing (via Pricing Service), 2. Reserve Inventory (via Inventory Service), 3. Authorize Payment (via Payment Service), 4. Create Order Record. If step 3 fails, step 1/2 must be compensated (rollback).\n* **Idempotency**: Ensure all services in the saga accept Idempotency Keys to prevent double-charging or double-stock deduction.", "dependencies": ["S7"]}, {"step_id": "S9", "title": "Extraction of Payments and Order Management", "description": "Complete the order lifecycle. Move payment integration and order status tracking out of the monolith.\n\n* **Payment Gateway**: Extract the integration with the 3 providers into a `Payment Service`. This service handles webhooks, refunds, and tokenization (PCI scope reduction).\n* **Order Management System (OMS)**: Move the database table `orders` and associated history into a new `Order Service`. It consumes the events generated by the Checkout Saga.\n* **Back-office Migration**: The back-office (300 staff) is likely server-rendered. Refactor these screens to consume the new `Order Service` APIs. Remove the back-office's direct SQL access to the orders table. This is crucial for reducing load on the monolith DB.", "dependencies": ["S8"]}, {"step_id": "S10", "title": "Legacy Cleanup and Peak Season Preparation", "description": "The monolith should now be a 'hollowed-out' shell (mostly just the legacy pricing rules inside a service or a 'legacy' module). We prepare for the peak sales in Jan/July.\n\n* **Database Downsizing**: Detach the schema ownership. The monolith should ideally only connect to a 'read-only' replica for historical data or a small remnant DB.\n* **Performance Tuning**: The new architecture is now the single point of failure. Optimize the message broker (Kafka) and API Gateway for 12x traffic.\n* **Chaos Engineering**: Run game-days testing resilience. Kill a service (e.g., Search) and ensure the storefront degrades gracefully (shows empty search results but allows cart access).\n* **Final Monolith Decommission**: Identify the remaining monolith code. Delete it. If it's just a 'legacy gateway', replace it with pure API routing. The 'Monolith' label should now refer only to the Pricing Service or similar, not a single deployable unit.", "dependencies": ["S9"]}], "estimated_complexity": "high", "success_metrics": "- **Zero Downtime**: Achieve 100% availability of the e-commerce platform throughout the 12 months, including planned maintenance windows.\n- **Deployment Independence**: New services can be deployed independently; no code commit forces a full 30-minute monolith downtime. Time-to-deploy for a new service < 5 minutes.\n- **Database Decoupling**: Eliminate cross-service SQL joins. The monolith database write load decreases by 90%.\n- **Peak Capacity**: System handles 12x traffic load (approx. 480k orders/day) with < 200ms latency at P95 during load tests.\n- **Search Latency**: Product availability reflected in search results within < 30 seconds of inventory update (replacing nightly rebuild).\n- **Pricing Stability**: 0% deviation in price calculation results between the new architecture and the legacy 'golden master' characterization tests."}Round 1 — refinement 1 of 2
The agents significantly improved their plans by adopting each other's strongest strategic insights. They all converged on a black-box extraction for the pricing module.
They also agreed on using Change Data Capture for database decoupling. The proposals are now much closer in structure, though Proposal 2 stands out for its rigorous handling of constraints.
The calls of this round
Influences: who took what from whom
| Round 1 ↓ · round 0 → | Proposal 1 | Proposal 2 | Proposal 3 | New steps |
|---|---|---|---|---|
| Proposal 1 |
kept6 | same titles1 analyst sees+1 / −1 | same titles1 analyst sees+1 / −1 | new12 |
| Proposal 2 |
same titles0 analyst sees+1 / −1 | kept4 | same titles0 analyst sees+1 / −1 | new14 |
| Proposal 3 |
same titles0 analyst sees+1 / −1 | same titles2 analyst sees+1 / −1 | kept3 | new7 |
The proposal reduced its step count and significantly improved its sequencing by adopting the black-box pricing strategy. It fixed the overly serialized dependency chain of its previous version by parallelizing read-heavy extractions. However, it still retains a somewhat rigid, linear progression compared to the adaptive approach of Proposal 2.
- Adopted explicit CDC and transactional outbox patterns for data synchronization.
- Introduced the black-box pricing extraction with a golden master characterization test suite.
- Improved sequencing by extracting Search and Catalogue earlier as a read-heavy pilot.
- Still relies on a rigid linear dependency chain rather than a calendar-driven scope ladder.
- The goal of raising test coverage to 70% for extract-candidate modules remains overly optimistic.
- Proposal 2 : Platform foundation with Kubernetes and CDC for event-driven data sync.
- Proposal 3 : Pricing module as a black box with golden master tests and real-time search indexing.
- Proposal 2 : Extracting Orders before Payments and extracting Pricing late without a golden master.
- Proposal 3: Compressing the plan into 10 steps.
+ Platform Foundation: Kubernetes, CI/CD, and Observability+ Strangler Pattern Setup: API Gateway, Feature Flags, and Service Mesh+ Domain Analysis and Service Boundary Definition via Event Storming+ Peak Season Protection Framework and Change Freeze Calendar+ Pricing Module Characterization: Black Box Baseline and Test Suite+ Change Data Capture and Event-Driven Data Sync Infrastructure+ Saga Pattern Framework and Distributed Transaction Orchestration+ Orders Service Extraction: Orchestrator for Checkout and Fulfillment+ Cart Service Extraction: Stateful Session Management+ Pricing Service Extraction: Black Box Wrapping and Golden Master Validation+ Returns Service Extraction and Order Lifecycle Completion+ Back-Office Service Aggregation and Staff User Experience+ Load Testing and Peak Capacity Validation Across Full System+ Team Reorganization and Independent Deployment Readiness+ Monolith Decommissioning and Legacy Code CleanupCurrent State Documentation & Target ArchitectureData Dependency Analysis & Dual-Write StrategyTest Coverage Audit & Improvement RoadmapPeak-Season Window Planning & Risk FrameworkObservability Foundation SetupFeature Flags, Containerization & API GatewayDeployment Pipeline & Automated RollbackEvent Bus & Service Mesh InfrastructureSaga Pattern Library & Order Orchestration FrameworkPricing/Promotions Service Extraction (Phase 1: Extract As-Is)Pricing/Promotions Service Refinement (Phase 2: Rules Refactoring)Order Service Extraction & Event StreamCheckout Service Composition via SagaBack-Office Integration with Service APIsStorefront & Mobile App RefactoringLegacy Database Deprecation & Data MigrationLoad Testing & Performance OptimizationDocumentation & Knowledge TransferProduction Stabilization & 30-Day Monitoring
The plan produced
1. Platform Foundation: Kubernetes, CI/CD, and Observability new
Establish the technical foundation for independent service deployment and operation before touching the monolith architecture.
- Provision Kubernetes cluster with dev/staging/prod namespaces, or equivalent managed cloud platform (ECS/App Engine)
- Deploy centralized logging (ELK or Loki), metrics (Prometheus/Grafana), and distributed tracing (Jaeger)
- Implement CI/CD pipelines for independent service deployments (GitHub Actions/GitLab CI/ArgoCD)
- Set up secrets management (Vault) and configuration management (Consul/Spring Cloud Config)
- Create observability dashboards for: order throughput, latency percentiles (P50/P95/P99), error rates, database load
- Define SLOs and alerting: order processing latency p99 < 5 seconds, checkout success rate > 99.5%, payment auth speed < 2 seconds
2. Strangler Pattern Setup: API Gateway, Feature Flags, and Service Mesh (after 1) new
Deploy the infrastructure layer that enables gradual traffic migration from monolith to services without downtime.
- Deploy API gateway (Kong or AWS ALB) in front of monolith; all traffic routes through gateway
- Implement feature flag system (LaunchDarkly or Unleash) to decouple deployment from traffic routing
- Set up service mesh (Istio or Linkerd) for inter-service communication, mTLS, and circuit breakers
- Containerize monolith as-is (Docker) so it can run alongside new services
- Instrument monolith with event publishing capability: add transactional outbox table for domain events
- Create blast radius containment: rate limiting, bulkheads, and timeouts at gateway level
3. Domain Analysis and Service Boundary Definition via Event Storming (after 2) from P3 step 2
Map the monolith's business domains and dependencies to identify safe extraction sequence and service boundaries.
- Run event storming workshops with all five teams; map customer journeys (Browse → Cart → Checkout → Order → Fulfillment → Returns)
- Create dependency matrix: which tables, stored procedures, and methods are accessed by each domain
- Use code hotspot analysis (SonarQube, CodeScene) to find logical coupling and identify decoupling opportunities
- Define service extraction sequence based on coupling and business risk: prioritize read-heavy (Search), well-bounded (Inventory), and identity (Customer) over complex (Pricing, Checkout)
- Document all cross-module joins; mark which ones must be eliminated vs. which can tolerate eventual consistency
- Identify stored procedures that span multiple domains; plan refactoring or replication strategy
4. Peak Season Protection Framework and Change Freeze Calendar (after 3) new
Establish hard boundaries to protect January and July sales from destabilizing changes.
- Map annual peak periods: January sales (peak revenue), July sales, plus promotional events
- Define 6-week freeze windows: 4 weeks before + 2 weeks during each peak season; no major extractions or refactors during freeze
- Identify lowest-risk windows in each month for incremental changes (hotfixes, small extractions, data migrations only)
- Create rollback runbooks for every step: how to revert traffic routing, database changes, and service deployments in < 30 minutes
- Establish incident escalation and communication plan: business owners notified of any changes near peak season
- Plan load testing outside freeze windows: validate 12x capacity (480k orders/day) for each service before peak season
5. Pricing Module Characterization: Black Box Baseline and Test Suite (after 3) new
Thoroughly document the 200k LOC pricing engine behavior before any extraction attempt, eliminating unknown risk.
- Analyze and document all pricing rules: country-specific logic, currency handling, promotional rules, edge cases
- Create comprehensive characterization test suite: record input/output for all 8 countries × 3 currencies × major promotional scenarios
- This test suite becomes the 'golden master': any new pricing service must match 100% of outputs
- Build test data set covering: normal pricing, discounts, bulk pricing, regional pricing, multi-currency edge cases, seasonal promotions
- Document all dependencies: which customer attributes, product attributes, inventory levels, and time-based factors affect pricing
- Establish CI gate: pricing service extraction cannot proceed until characterization tests pass 100%
6. Test Coverage Improvement: Target 70% for Extract-Candidate Modules (after 3)
Increase test confidence for modules scheduled for early extraction; reduce rollback risk from test blindness.
- Audit current test coverage by module; identify gaps in: Search, Catalogue, Inventory, Cart, Customer
- Implement integration tests for critical flows: order creation, payment processing, inventory updates, customer account creation
- Add contract tests (Pact) between modules to catch API breaking changes early
- Use mutation testing to verify test quality: tests must catch injected bugs
- Target 70%+ coverage for Search, Inventory, Customer, Cart, Payments modules
- Establish automated quality gates: no service extraction if module coverage < 60%; no production deployment if < 70%
- Create load test suites for peak scenarios: simulate 40k→480k order escalation for each module
7. Change Data Capture and Event-Driven Data Sync Infrastructure (after 2, 5) new
Build the plumbing to eliminate cross-module database joins and enable eventual consistency between services.
- Deploy CDC tool (Debezium with Kafka/Pulsar) to stream PostgreSQL WAL changes to message broker
- Refactor monolith to use transactional outbox pattern: all domain events written atomically in same transaction as business data
- Create event schema versioning: events must be backwards/forwards compatible as services evolve
- Implement dual-write mechanism: during transition, write to both monolith database and new service database
- Set up event relay: monolith publishes events (OrderPlaced, PaymentAuthorized, InventoryReserved) to Kafka
- Define eventual consistency model: which operations can tolerate delayed propagation vs. which require immediate consistency
8. Search and Catalogue Service Extraction: Read-Heavy Pilot Service (after 6, 7)
Extract the first service: read-heavy, low transactional risk, validates the entire strangler fig pattern.
- Build new Catalogue and Search service: REST API for product lookup, search, and filtering
- Create new database schema (PostgreSQL): product data, categories, attributes; use Elasticsearch/OpenSearch for real-time search indexing
- Subscribe to CDC events from monolith: ProductUpdated events trigger real-time search index refresh (eliminates nightly Lucene rebuild, improves freshness to < 1 minute)
- Implement dual-read path: feature flag controls whether requests hit monolith Lucene or new Search service
- Use API gateway shadow traffic: send requests to both old and new service; compare responses; alert on differences
- Gradually shift traffic: 10% → 25% → 50% → 100% using feature flags and canary deployments
- Maintain dual-write for 2 weeks post-cutover to verify correctness; then deprecate monolith search code
9. Inventory Service Extraction: Real-Time Warehouse Synchronization (after 7, 8)
Extract inventory as second service: async boundary, directly integrates with warehouse system, eliminates 15-minute sync latency.
- Build Inventory service: consumes warehouse file feed (SFTP/API) directly instead of monolith polling
- Create inventory database schema: stock levels, reservations, holds per product per location
- Publish inventory events: StockLevelChanged, ReservationCreated, ReservationReleased to Kafka
- Implement reservation system (prepare for saga pattern): inventory holds items during checkout, releases on order confirmation or timeout
- Dual-write monolith inventory data during transition: maintain consistency between old and new
- Test warehouse sync at peak load: ensure 15-minute sync windows do not slip under 480k daily orders
- Validate that all cart and checkout code calls inventory service via API (or consumes events) rather than direct SQL join
- Gradual traffic shift: test with non-critical inventory queries first, then critical paths
10. Customer and Loyalty Service Extraction: Identity Decoupling (after 9)
Extract customer accounts and loyalty programs: enables independent auth scaling and multi-tenant loyalty rules.
- Build Customer service: JWT token generation, profile management, address management, identity verification
- Create customer database schema (separate from monolith): User, Address, Profile; replicate to read-only cache where needed
- Implement loyalty points service: handles country-specific loyalty rules (8 countries, different point accrual rates)
- Sync customer data via events: monolith publishes CustomerCreated, CustomerUpdated, CustomerDeleted to Kafka
- API gateway routes: /api/login, /api/profile, /api/loyalty to new Customer service; monolith drops these endpoints
- Ensure backwards compatibility: versioned API responses so old mobile app clients still work
- Test at peak concurrency: concurrent logins, loyalty point updates under 480k orders/day load
- Implement session management: distributed sessions (Redis-backed) so users stay logged in during monolith↔service transitions
11. Saga Pattern Framework and Distributed Transaction Orchestration (after 7) new
Implement the orchestration layer required for multi-service transactions before extracting payment and order services.
- Build saga pattern library: support both choreography (event-driven) and orchestration (centralized coordinator) patterns
- Implement compensating transactions: if payment fails during checkout, inventory reservation and pricing calc must roll back
- Add idempotency framework: all services accept idempotency-key headers; prevent duplicate charges, double-deductions
- Handle timeouts and retries: exponential backoff, circuit breakers, manual intervention for stuck sagas
- Create saga log: record saga execution with state transitions for auditing, debugging, and replay
- Test saga execution under peak load and network failures: simulate payment provider latency, inventory service timeouts
- Document saga flows: checkout saga (price → reserve inventory → authorize payment → create order), return saga, refund saga
- Implement distributed tracing: each saga step is traced end-to-end for observability
12. Payment Service Extraction: PCI-Scoped and Secure (after 11)
Extract payment processing with extreme security rigor: handles card data, three payment providers, regulatory compliance.
- Build Payment service: integration with all three payment providers (tokenization, authorization, capture, refund)
- Implement PCI-DSS compliance: no raw card data in logs, encrypted transport, minimal data exposure in monolith
- Handle payment declines and fraud: integrate fraud detection, implement retry logic for transient failures
- Create idempotent payment requests: prevent double-charging if client retries or network fails mid-request
- Implement webhook handling: payment providers notify service of async events (captures, chargebacks, refunds)
- Design rollback procedure: if new service fails catastrophically, fall back to direct monolith payment handling (via feature flag)
- Load test: 500+ payments/sec at peak (baseline 40k orders/day → 480k orders/day = ~550 payments/sec)
- Test all three provider scenarios: happy path, declines, timeouts, chargebacks
13. Orders Service Extraction: Orchestrator for Checkout and Fulfillment (after 12) new
Extract order management: central service coordinating checkout saga and order lifecycle across all services.
- Build Order service: order creation, status tracking, order querying API for all business users (inventory, fulfillment, customer service teams)
- Implement checkout orchestrator: accepts cart (items, customer, delivery address) → triggers saga → creates order record on success
- Integrate with Payment service (authorize payment), Inventory service (reserve stock), Pricing service (calculate total), Customer service (loyalty points)
- Implement order state machine: validate state transitions (Pending → Confirmed → Shipped → Delivered), prevent invalid transitions
- Create order event stream: OrderCreated, PaymentAuthorized, InventoryReserved, OrderConfirmed, OrderShipped for other services to consume
- Use event sourcing: maintain immutable log of all order state changes for audit trail and replay capability
- Test concurrent order processing at peak load: 40k→480k orders/day; ensure no race conditions, duplicate orders, or lost transactions
- API design: query orders by customer ID, order ID, SKU, date range; sorting and filtering for back-office use
14. Cart Service Extraction: Stateful Session Management (after 10)
Extract shopping cart as stateful service: decouples browsing/cart operations from order processing, independent scaling.
- Build Cart service: add/remove items, update quantities, persist session state, apply coupons/discounts
- Implement cart storage: Redis for session-backed stateless carts, or PostgreSQL with session affinity for persistent carts
- Integration with services: calls Catalogue service (product availability), Inventory service (stock check), Pricing service (cart totals)
- API design: cart operations (add/remove/view), subtotals with pricing breakdowns, coupon application
- Implement session stickiness: API gateway routes same user to same Cart service instance (or share Redis state)
- Test at peak concurrency: concurrent cart updates from same user (one browser tab → mobile app → browser again)
- Ensure idempotency: adding same item twice returns same cart state, no duplicates
- Gradual traffic shift: test with non-critical users first, then ramp up
15. Pricing Service Extraction: Black Box Wrapping and Golden Master Validation (after 5, 13) new
Extract pricing logic as black box service using characterization tests to ensure 100% correctness preservation.
- Move 200k LOC pricing logic into dedicated Pricing service with own codebase
- Service exposes API: accepts product IDs, customer attributes, location, time, inventory levels → returns price, applicable promotions, currency
- Use dedicated read-replica database with pricing tables only (no cross-joins to other domains)
- Run shadow mode traffic: send live pricing requests to both old monolith and new service; compare outputs; alert on any divergence
- Validation gate: pricing service must match characterization test suite 100% for all 8 countries, 3 currencies, all tested scenarios
- Feature flag control: gradually shift production traffic once shadow mode validates correctness
- Document decision: this service remains a black box (we don't refactor internal logic); future teams can safely extend without fear
- Plan Phase 2 refactoring separately: after service is stable in production, optionally decompose into rules engine (Drools) in future quarter
16. Returns Service Extraction and Order Lifecycle Completion (after 13, 15) new
Extract returns handling: completes order lifecycle, depends on Orders and Pricing services being stable.
- Build Returns service: process return requests, validate return eligibility, calculate refunds (using Pricing service), manage return shipping
- Integrate with Orders service: fetch order data, verify items purchased
- Integrate with Inventory service: return items to stock after confirmation
- Integrate with Payment service: process refunds back to original payment method
- API design: create return request, track return status, generate return shipping labels
- Implement return state machine: Requested → Approved → Shipped → Received → Refunded
- Consumer integration: back-office staff (or customer self-service) calls Returns service APIs instead of monolith
- Test return flows at peak load: validate no inventory/refund race conditions
17. Back-Office Service Aggregation and Staff User Experience (after 13, 16) new
Update back-office (300 staff) to consume new service APIs; eliminate monolith direct database access.
- Create service aggregation endpoints: orders endpoint calls Order + Payment + Inventory + Shipping services; returns endpoint calls Returns service
- Implement API gateway service discovery: back-office transparently calls services even if they move/scale
- Add caching layer: frequently accessed data (customer profiles, order lists) cached with TTL to reduce service latency
- Implement timeouts and graceful degradation: if one service is slow, show cached data or partial results
- Refactor back-office UI: replace monolith SQL queries with REST API calls
- Test with 300 concurrent staff users: search across orders/customers, filtering by date/status, bulk actions
- Implement distributed tracing: back-office requests are traced across all services for debugging
- Add retry logic: transient failures (network blips) automatically retry; permanent failures show user-friendly errors
18. Load Testing and Peak Capacity Validation Across Full System (after 17) new
Validate new distributed architecture handles peak load (480k orders/day) without degradation; stress test before peak seasons.
- Simulate realistic peak load: 480k orders/day (12x baseline), 8 countries, 3 currencies, 4 languages simultaneously
- Test sequence: base load → ramp to 480k → sustain for 30 minutes → spike to 1.5x peak → graceful degradation
- Measure latencies: checkout flow (cart → confirmation) p95 < 5 seconds, payment authorization < 2 seconds, search < 1 second
- Monitor service-level metrics: requests/sec, error rates, database query times, message broker throughput, cache hit rates
- Identify and optimize bottlenecks: pricing calculations, search queries, payment provider round-trip time, inventory reservations
- Test database connection pools: ensure no exhaustion or deadlocks under peak load
- Validate message broker (Kafka): 480k messages/day throughput, latency, durability
- Create realistic user behavior: product browsing → search → add to cart → checkout flows, not just load
- Fail-over testing: kill one service (e.g., Search); verify system degrades gracefully, no cascading failures
- Load test outside freeze windows; complete before January/July peak seasons
19. Team Reorganization and Independent Deployment Readiness (after 18) from P2 step 14
Reorganize teams around services to enable independent deployments and long-term operational autonomy.
- Reorganize five teams: from business-function-based (Pricing team, Fulfillment team) to stream-aligned (Search Service team, Orders Service team)
- Assign service ownership: each team owns their service's codebase, CI/CD pipeline, database schema, on-call rotation, SLOs
- Implement internal developer platform (IDP): golden path templates, self-service deployments, secrets rotation, observability dashboards
- Establish SLOs per service: error budget, latency targets, availability targets
- Create cross-team API contracts: service teams sign off on API changes; breaking changes trigger communication plan
- Set up inter-service communication: API versioning, deprecation periods, backward compatibility requirements
- Plan on-call: each team on-call for their service; pager rotation, incident response training
- Document service dependencies: which services call which; upstream/downstream impact analysis
20. Monolith Decommissioning and Legacy Code Cleanup (after 19) new
Safely retire monolith code once all services are stable and production-proven.
- Audit monolith codebase: identify dead code (Search, Catalogue, Inventory, Customer, Orders, Payments, Cart, Returns logic)
- Delete extracted service code from monolith; remove dual-write logic once service has proven stable (30+ days in production)
- Gradually reduce monolith database: archive or migrate old tables, remove cross-module stored procedures
- Plan monolith decommissioning: if monolith becomes shell (mostly unused), decide: keep as fallback or shut down completely
- Maintain 90-day read-only archive of monolith database for emergency historical queries and regulatory retention
- Update backup/recovery procedures: shift from single monolith snapshot to per-service snapshots
- Document architectural decisions: why services were split this way, what problems were solved, what trade-offs were made
- Create incident playbooks: common failure modes, resolution steps, escalation paths
- Close out migration project: update runbooks, retire temporary monitoring, establish steady-state operational procedures
- Celebrate: migration complete, new architecture proven at peak load, five teams deploying independently
- Zero unplanned downtime during 12-month migration; all maintenance windows scheduled and communicated; zero production incidents caused by migration
- Peak seasons (January and July sales) proceed with zero degradation: 480k orders/day processed with p95 checkout latency < 5 seconds, payment authorization < 2 seconds, zero payment processing failures
- All eight services independently deployable: no code commits force monolith downtime; new service deployment < 5 minutes; deployment frequency increases from bi-weekly (monolith) to daily (services) where applicable
- Test coverage increased from 25% to 70%+ for all extracted services (Search, Inventory, Customer, Cart, Orders, Payments, Returns); characterization test suite for Pricing passes 100% before service extraction
- Every service deployment is rollback-able in < 30 minutes: documented procedures tested monthly; rollback automated where possible
- Data consistency validated: monthly reconciliation between service databases and monolith shows zero inconsistencies; dual-write period completes successfully (2 weeks per service)
- Order processing SLA maintained: cart → confirmation latency unchanged or improved; maintained under 5 seconds at peak load (480k orders/day)
- All five teams deploying independently by month 12: no cross-team deployment coordination required; each team owns service, deployment pipeline, on-call rotation
- Search latency improved or maintained: product availability reflected in search results within < 1 minute of inventory update (vs. previous nightly rebuild), baseline latency unchanged
- Inventory synchronization preserved: no missed 15-minute warehouse sync cycles during migration; 100% of daily inventory updates processed
- Back-office operations unaffected: 300 staff members seamlessly using new service APIs; service aggregation endpoints maintain < 500ms p95 latency
- Payment processing: zero regressions with all three payment providers; fraud detection remains active; PCI-DSS compliance maintained; idempotency prevents duplicate charges
- Event-driven architecture validated: Kafka message broker handles 480k messages/day at peak; no message loss or ordering violations
- Rollback capability proven: every step validated to be reversible; no permanent cutover without 30-day validation period and green light from peak season calendar
[SYSTEM]
You are an expert assistant in complex project planning.
Your task is to generate a detailed and structured action plan to reach the main objective in the most professional and most detailed way, no matter how much work or steps will be needed to perform.
Use your internal reasoning processes to think deeply about the problem and create the most comprehensive plan possible.
Take as much time and space as you need to think through all aspects of the problem.
After your thorough analysis, answer with the plan in the requested structure.
Every text field you write will be read by a busy person, so write for them: short sentences, one idea each, in short paragraphs. Text fields accept Markdown: separate paragraphs with a blank line, use a bullet list when you enumerate things and plain paragraphs when you explain or argue, and bold at most one key phrase per paragraph. A text of more than three sentences must be split into paragraphs; never deliver a single unbroken block of text.
[HUMAN]
Main Objective: "A mid-size European fashion retailer runs its e-commerce on a 10-year-old monolith: Java 8 / Spring, about 2 million lines, one PostgreSQL database of 1.2 TB with 350 tables and heavy use of stored procedures and cross-module joins. It serves 8 countries, 3 currencies and 4 languages, with about 40,000 orders a day and peaks of 12x during sales. The monolith contains: the storefront (server-rendered, plus a separate mobile app hitting the same endpoints), catalogue and search (a Lucene index rebuilt nightly), pricing and promotions (the most complex module, 200,000 lines, with country-specific rules nobody fully understands), cart and checkout with three payment providers, order management, inventory synchronised every 15 minutes with the warehouse system via file exchange, customer accounts and loyalty, returns, and a back-office used by 300 staff. Deployments happen every two weeks as a single artefact with a 30-minute maintenance window; test coverage is 25% and mostly unit tests. Five teams of 8 developers, each organised around a business area but all committing to the same repository.
Plan the migration to independently deployable services over 12 months with no feature freeze, no unplanned downtime and the ability to roll back every step, preserving the peak-season capacity (sales in January and July must not be put at risk)."
For your consideration and refinement, here are proposals from the previous round:
Previous Proposal 1 (ID: 1a154427-5ec4-44d9-aff2-f7dd482a0601, Agent: claudeHaiku4.5_initial_1 - YOUR OWN previous proposal, LLM: anthropic/claude-haiku-4-5):
Estimated Complexity: high
Success Metrics: - All 8 services independently deployed and running in production with zero unplanned downtime during 12-month migration
- Zero data inconsistencies between service-specific databases (validated by monthly reconciliation)
- January and July peak seasons proceed with no degradation: 480k orders/day processed within 5-second checkout SLA
- Test coverage increased from 25% to 70%+ for all extracted services
- Every service deployment is fully automated; manual rollback procedures tested and <30 minutes to execute
- Order processing latency (cart → confirmation) unchanged or improved: maintained under 5 seconds at peak load
- All 5 teams deploying independently: no cross-team deployment coordination required after cutover
- Pricing/promotions service successfully extracted with all 200k LOC of country-specific rules preserved and validated
- Search latency improved or maintained despite architectural change
- Inventory synchronization with warehouse continues reliably: no missed 15-minute sync cycles
- Back-office operations for 300 staff members unaffected by migration; service aggregation endpoints maintain <500ms latency
- Zero payment processing regressions: all three payment providers functioning, fraud detection active, PCI-DSS compliance maintained
Steps (24):
1. Current State Documentation & Target Architecture
Create a detailed map of the monolith to inform service extraction strategy.
- Audit all modules: storefront, catalogue, search, pricing/promotions, cart, checkout, orders, inventory, customers, loyalty, returns, back-office
- Map dependencies between modules, identifying cross-module calls and data flows
- Model future bounded contexts using Domain-Driven Design
- Create technology inventory (libraries, frameworks, protocols)
- Document interface contracts for each module
- Identify which teams own which modules for organizational alignment
2. Data Dependency Analysis & Dual-Write Strategy (depends on: 1)
Untangle the 1.2TB database to support service independence without blocking progress.
- Map all 350 tables to future service domains
- Identify cross-service joins and stored procedures that span domains
- Design per-service database schemas with minimal denormalization
- Create data versioning framework to support rollback
- Plan dual-write patterns: how old monolith and new services will sync during transition
- Document eventual-consistency requirements and conflict resolution
- Design data migration runbooks with clear rollback steps
3. Test Coverage Audit & Improvement Roadmap (depends on: 1)
Build confidence for service extraction by eliminating test blindness.
- Audit current 25% test coverage by module
- Identify coverage gaps in modules scheduled for early extraction
- Establish target of 70%+ coverage for modules being extracted
- Prioritize integration tests over unit tests given monolith complexity
- Create quality gates: no service extraction below 60% module coverage
- Plan for continuous improvement during extraction phases
4. Peak-Season Window Planning & Risk Framework (depends on: 1)
Protect January and July sales by scheduling extractions during safe windows.
- Map annual peak periods: January sales (peak orders), July sales, plus any promotional events
- Define 4-week freeze windows before/during peaks
- Identify lowest-risk windows in each month for major changes
- Create rollback procedures that execute in <30 minutes
- Establish monitoring escalation for changes made near peak season
- Document communication plan with business teams
5. Observability Foundation Setup
Instrument the system for real-time visibility during migration.
- Deploy centralized logging (ELK, Splunk, or similar)
- Set up metrics collection (Prometheus, Datadog, or similar)
- Implement distributed tracing (Jaeger, Zipkin) for request flows across services
- Create dashboards for: requests/sec, error rates, latency percentiles, database load
- Define SLOs: order processing latency p99, checkout success rate, payment authorization speed
- Set up alerts for SLO violations and anomalies
6. Feature Flags, Containerization & API Gateway
Build the technical foundation for canary deployments and controlled traffic routing.
- Implement feature flag system (LaunchDarkly, custom Spring Boot solution, etc.)
- Containerize monolith and all new services (Docker)
- Set up container orchestration (Kubernetes or similar) with service templates
- Deploy API gateway (Kong, AWS ALB) with routing rules
- Implement service-to-service authentication (mTLS, JWT)
- Configure rate limiting and circuit breakers at gateway
7. Deployment Pipeline & Automated Rollback (depends on: 6)
Enable safe, automated deployments with reliable rollback capability.
- Implement CI/CD pipeline with automated testing gates
- Set up blue-green deployment: run old and new versions in parallel, switch traffic atomically
- Build canary deployment capability: route 5%→10%→50%→100% of traffic gradually
- Automate rollback: trigger on error rate threshold, latency spike, or manual command
- Create deployment runbooks for each service
- All deployments must be independent; monolith keeps 2-week cycle until fully extracted
8. Test Coverage Improvement to 70%+ (depends on: 3)
Close test gaps before extracting services to reduce rollback risk.
- Implement integration tests for key flows: order creation, payment processing, inventory updates
- Add contract tests between modules to catch breaking changes
- Use mutation testing to verify test quality
- Target 70%+ coverage for: pricing module, payment module, order management
- Establish automated quality gates: coverage <70% blocks extraction of that service
- Include tests for peak-load scenarios (40k→480k orders)
9. Search/Catalogue Service Extraction & Validation (depends on: 7, 8, 3)
Extract the first service: search is read-heavy, isolated, and low-risk.
- Extract catalogue and search indexing logic from monolith
- Build as independent Spring Boot service with own codebase/deployment
- Create new database schema for catalogue (subset of 350 tables)
- Implement dual-write: monolith writes to both old Lucene index and new service
- Implement canary routing: API gateway sends 10% of search requests to new service, monitor latency and correctness
- Validate results match between old and new service (checksums on result sets)
- Gradually increase traffic: 10%→25%→50%→100%
- Keep dual-write active for 2 weeks post-cutover for rollback safety
10. Event Bus & Service Mesh Infrastructure (depends on: 9)
Build async communication layer required for multi-service coordination.
- Deploy message broker (Kafka recommended for ordering guarantees and peak load of 40k/sec)
- Define domain events: OrderPlaced, PaymentAuthorized, InventoryReserved, etc.
- Implement event schema versioning and compatibility
- Set up service discovery (Consul, Kubernetes DNS)
- Implement distributed configuration management
- Create event publishing library for services to use
- Document saga patterns for multi-step workflows
- Test message broker under peak load (480k messages/day)
11. Inventory Service Extraction & Warehouse Sync (depends on: 10)
Extract inventory as second service: well-bounded, drives warehouse sync complexity.
- Extract inventory logic and reservation system
- Build inventory service with own database schema
- Implement dual-write from monolith to both old and new inventory data
- Preserve existing 15-minute warehouse file exchange, but now via service
- Create inventory events: ReservationCreated, ReleaseRequested
- Implement canary rollout: gradual traffic shift like search service
- Test warehouse sync under peak load
- Validate inventory consistency across monolith and new service before full cutover
12. Customer/Loyalty Service Extraction & Auth Refactoring (depends on: 10)
Extract customer accounts and loyalty: enables independent scaling of auth layer.
- Extract customer account and loyalty program logic
- Build customer service with own database schema
- Separate authentication from monolith: implement API for token validation
- Support multi-tenant loyalty rules (8 countries, country-specific points rules)
- Implement canary rollout with real customer sessions
- Create backwards-compatible customer APIs
- Test account operations at peak concurrency (concurrent logins, loyalty point updates)
- Plan for session management: ensure distributed sessions work across services
13. Saga Pattern Library & Order Orchestration Framework (depends on: 10)
Build the framework for managing distributed transactions across services.
- Implement saga pattern library: choreography-based (event-driven) and orchestration-based patterns
- Support compensating transactions: if payment fails, return inventory reservation
- Handle timeouts and retries with exponential backoff
- Implement idempotency keys to prevent duplicate charges on retries
- Test saga execution under peak load and network failures
- Document patterns for: order placement saga, payment saga, return saga
- Create distributed tracing for saga flows
14. Pricing/Promotions Service Extraction (Phase 1: Extract As-Is) (depends on: 13)
Begin extraction of most complex module (200k LOC) without initial refactoring.
- Extract pricing engine as-is with minimal refactoring to reduce initial risk
- Preserve all country-specific rules and business logic
- Build service boundary: accept pricing requests, return prices/promotions
- Create feature tests that document all 200k LOC behavior
- Map all promotion types to test scenarios
- Test with real country/currency/language combinations
- Implement as service behind same interface initially
- Prepare for Phase 2 refactoring once stable in production
15. Pricing/Promotions Service Refinement (Phase 2: Rules Refactoring) (depends on: 14)
Gradually improve pricing service maintainability without breaking production.
- Document the 200k LOC of complex rules in machine-readable format
- Refactor rules engine into composable components
- Build DSL for country-specific promotion rules
- Decompose monolithic rule evaluation into smaller decision trees
- Use feature flags to A/B test refactored rules vs old implementation
- Optimize performance: reduce calculation time for promotions at checkout
- Validate that refactored logic matches original behavior across all countries
16. Payment Service Extraction & Security Hardening (depends on: 13)
Extract payment processing with extreme rigor given PCI/regulatory requirements.
- Separate payment logic from checkout: payment validation, three-provider integration
- Build payment service with encrypted credential storage, no raw card data in logs
- Implement fraud detection integration and decline handling
- Audit for PCI-DSS compliance: minimal data exposure, encrypted transport
- Implement E2E testing for all three payment provider scenarios
- Load test payment service: 500+ payments/sec at peak
- Implement idempotent payment requests: prevent double-charging on failures
- Create detailed rollback procedures: how to fall back to direct monolith payment handling
17. Order Service Extraction & Event Stream (depends on: 13, 16)
Extract order management: central service coordinating multiple workflows.
- Extract order creation, status tracking, and management logic
- Build order service with event stream: OrderCreated, PaymentAuthorized, InventoryReserved, OrderConfirmed
- Support order querying by all 5 teams (inventory, fulfillment, customer service, etc.)
- Implement order event sourcing for audit trail and replay capability
- Create order state machine: validate state transitions
- Test concurrent order processing at peak load (40k orders/day)
18. Checkout Service Composition via Saga (depends on: 17)
Compose checkout from independent payment, inventory, and order services using sagas.
- Build checkout service that orchestrates: cart validation → pricing calculation → inventory reservation → payment authorization → order creation
- Use saga pattern: if payment fails, release inventory reservation automatically
- Implement distributed transaction semantics: all-or-nothing guarantee
- Support three payment providers transparently
- Test all failure scenarios: payment declines, inventory unavailable, warehouse system down
- Implement timeout handling: what happens if inventory service is slow at peak
- Validate checkout latency remains <5 seconds at peak load
19. Back-Office Integration with Service APIs (depends on: 18)
Update back-office (used by 300 staff) to coordinate across all services.
- Create service aggregation endpoints: orders endpoint calls order service + payment service + inventory service
- Update back-office UI to call new service APIs instead of monolith
- Implement service discovery: handle service availability transparently
- Create caching layer: reduce latency for frequently accessed data
- Test with 300 concurrent staff users
- Implement search across all orders/customers via service APIs
- Add retry logic and timeouts to handle service failures gracefully
20. Storefront & Mobile App Refactoring (depends on: 19)
Update client applications to use new service architecture transparently.
- Update server-rendered storefront templates to call service APIs
- Update mobile app endpoints (already separate, now points to services via gateway)
- Implement client-side caching: reduce latency impact of distributed calls
- Maintain backwards compatibility: old clients must still work
- Update API versioning: enable service changes without breaking clients
- Implement request tracing: correlate user requests across services
- Test storefront and mobile under peak load scenario (480k orders/day)
21. Legacy Database Deprecation & Data Migration (depends on: 20)
Safely decommission the monolith database once all services are independent.
- Verify all data has been migrated to service-specific databases
- Maintain 2-week read-only access to old database for emergency queries
- Archive old database snapshots (regulatory requirement for order history)
- Update backup/recovery procedures: now per-service instead of monolith
- Verify no remaining cross-service joins depend on monolith schema
- Document data mapping for future reference
- Decommission old database infrastructure
22. Load Testing & Performance Optimization (depends on: 21)
Validate new architecture meets production capacity requirements.
- Simulate peak load scenario: 480k orders/day (40k baseline × 12)
- Test across 8 countries, 3 currencies, 4 languages simultaneously
- Identify bottlenecks: service latency, database query performance, message broker throughput
- Optimize hot paths: pricing calculations, search queries, payment processing
- Test cache effectiveness: Lucene search response times, pricing cache hit rates
- Validate database connection pools don't exhaust under peak load
- Create load testing environment: realistic data, all 5 teams' concurrent usage
23. Documentation & Knowledge Transfer (depends on: 22)
Codify migration experience and new architecture for long-term success.
- Document final service boundaries: APIs, responsibilities, data ownership
- Create operational runbooks: how to deploy each service, how to handle common failures
- Record architecture decision log: why services were split this way
- Document data consistency model: eventual consistency patterns used
- Create troubleshooting guides: common issues and resolutions
- Train each team on their service and API contracts with other services
- Record key decisions and trade-offs (e.g., why search is separate from catalogue, why pricing is monolithic within its service)
24. Production Stabilization & 30-Day Monitoring (depends on: 23)
Establish stable operation and prove architecture meets requirements.
- Run 30-day monitoring period observing: error rates, latency, resource utilization
- Establish performance baselines: P99 latency per service, throughput, error rates
- Document SLO achievements: order processing speed, payment success rate, search latency
- Create incident playbooks based on observed issues
- Validate peak-load handling (Jan/July sales go normally through new architecture)
- Establish team on-call procedures for service alerts
- Plan for service scaling: autoscaling policies, capacity planning
- Complete full rollback verification: ensure rollback to monolith is always possible
Previous Proposal 2 (ID: f92888a9-2fa0-4ee5-a4ab-426fc426ffab, Agent: deepseek-flash_initial_2, LLM: deepseek/deepseek-flash):
Estimated Complexity: high
Success Metrics: - 100% of planned service extractions completed within 12 months.
- Zero unplanned downtime during January and July peak sales.
- All new services independently deployable with <5 minute lead time.
- 100% of deployments rollback-able within 5 minutes.
- 80% of traffic served by new services by end of 12 months.
- Test coverage increased to 60% for critical modules.
- Deployment frequency increased from bi-weekly to daily.
- Mean time to recovery (MTTR) < 30 minutes.
- Change failure rate < 15%.
- All stored procedures refactored or migrated to services.
- Database decomposed into 5+ independent databases.
- Peak load capacity sustained at 12x with <1% error rate.
Steps (15):
1. Mobilize Program and Define Target Architecture
Launch the migration program and define the target architecture. This step sets the foundation for all subsequent work.
Key activities:
- Establish a steering committee with business, architecture, and operations representatives.
- Conduct domain-driven design workshops to identify bounded contexts and service candidates.
- Define the target architecture: API gateway, service mesh, event-driven integration, and data ownership per service.
- Prioritize service extraction based on business value, risk, and coupling.
- Create architecture decision records (ADRs) and a service roadmap.
Output: a shared vision and prioritized backlog for the migration.
2. Build Platform Foundation for Independent Deployments (depends on: 1)
Build the platform foundation required for independent deployments. This includes infrastructure, tooling, and golden paths.
Key activities:
- Provision a Kubernetes cluster with namespaces for each service.
- Set up CI/CD pipelines per service using GitLab CI or ArgoCD.
- Deploy an API gateway (e.g., Kong) and service mesh (e.g., Istio) for traffic management.
- Implement observability: centralized logging (ELK), metrics (Prometheus/Grafana), and tracing (Jaeger).
- Set up secrets management (Vault) and configuration management.
- Create golden path templates for new services to reduce boilerplate.
Output: a production-ready platform where teams can deploy services independently.
3. Implement Strangler Fig Facade and Monolith Instrumentation (depends on: 2)
Implement the strangler fig facade and instrument the monolith. This allows incremental migration without disrupting users.
Key activities:
- Deploy the API gateway to route requests to the monolith or new services based on path or header.
- Modify the monolith to expose REST APIs for key domains (e.g., catalogue, customer).
- Implement the transactional outbox pattern to publish domain events from the monolith.
- Set up change data capture (CDC) from the monolith PostgreSQL to Kafka using Debezium.
- Introduce feature flags for routing and canary releases.
- Ensure all changes are backward compatible and can be rolled back.
Output: a facade that enables gradual traffic shifting and a data pipeline for synchronization.
4. Establish Continuous Delivery and Test Automation (depends on: 1)
Establish continuous delivery and test automation to support safe, frequent deployments.
Key activities:
- Increase automated test coverage for critical monolith modules (target 60%).
- Implement consumer-driven contract testing (Pact) between monolith and new services.
- Set up automated regression test suites for end-to-end flows.
- Integrate tests into CI/CD pipelines with quality gates.
- Enable blue-green and canary deployments for both monolith and services.
Output: a reliable deployment pipeline that supports rollback and rapid feedback.
5. Extract Catalogue and Search Service (depends on: 3, 4)
Extract the Catalogue and Search service. This is a read-heavy, low-coupling module, making it a good first candidate.
Key activities:
- Create a new Catalogue service with its own datastore (PostgreSQL for product data, Elasticsearch for search).
- Implement data synchronization from the monolith via CDC and events.
- Migrate read APIs for product listing and search to the new service via the gateway.
- Use feature flags to gradually shift traffic, with fallback to the monolith.
- Monitor performance and rollback if issues arise.
Output: an independently deployable Catalogue service serving a portion of traffic.
6. Extract Customer Accounts and Loyalty Service (depends on: 3, 4, 5)
Extract the Customer Accounts and Loyalty service. This service manages profiles, addresses, and loyalty points.
Key activities:
- Create a new Customer service with its own database.
- Synchronize data from the monolith via events (customer created, updated).
- Migrate profile management and loyalty APIs to the new service.
- Keep authentication in the monolith initially to reduce risk.
- Redirect customer API calls to the new service gradually.
Output: an independently deployable Customer service with data ownership.
7. Extract Inventory Service (depends on: 3, 4)
Extract the Inventory service. This service consumes the warehouse file feed directly and maintains real-time inventory.
Key activities:
- Create an Inventory service that reads the warehouse file feed (SFTP) and parses it.
- Publish inventory update events to Kafka.
- Migrate inventory queries from the monolith to the new service.
- Ensure the monolith and other services consume inventory events instead of querying the monolith DB.
Output: an independently deployable Inventory service with real-time updates.
8. Extract Returns Service (depends on: 3, 4, 6)
Extract the Returns service. This module is relatively independent and can be extracted early.
Key activities:
- Create a Returns service with its own database.
- Consume order and customer events to validate returns.
- Migrate returns UI and APIs to the new service.
- Ensure integration with order management for refunds.
Output: an independently deployable Returns service.
9. Peak Season Readiness and Resilience Engineering (depends on: 1)
Prepare for peak seasons and implement resilience engineering. This is critical to avoid downtime during January and July sales.
Key activities:
- Conduct load testing for 12x peak on new services and the monolith.
- Implement circuit breakers, bulkheads, rate limiting, and auto-scaling.
- Define change freeze periods: one month before and during January and July sales.
- Plan migration activities outside freeze windows.
- Run game days for failure scenarios and rollback drills.
Output: a system that can withstand peak loads and a schedule that protects peak seasons.
10. Extract Cart Service (depends on: 3, 4, 7)
Extract the Cart service. The cart is a stateful component that requires careful handling.
Key activities:
- Create a Cart service with its own datastore (e.g., Redis or PostgreSQL) for session and cart items.
- Use the API gateway to route cart operations.
- Synchronize with the monolith via events for product and inventory validation.
- Ensure idempotency and session stickiness.
- Gradually migrate cart traffic using feature flags.
Output: an independently deployable Cart service.
11. Extract Order Management and Checkout Orchestration (depends on: 10, 6, 7, 9)
Extract Order Management and Checkout Orchestration. This is the core transactional flow and requires a saga pattern.
Key activities:
- Create an Order service that orchestrates checkout using the saga pattern.
- Integrate with payment providers, inventory, pricing, and customer services.
- Migrate order placement and management APIs.
- Use events for order status updates.
- Ensure distributed transaction consistency and compensation logic.
Output: an independently deployable Order service handling the checkout flow.
12. Extract Pricing and Promotions Service (depends on: 11)
Extract the Pricing and Promotions service. This is the most complex module with 200k lines of rules.
Key activities:
- Analyze and document the existing pricing rules and country-specific logic.
- Implement a new Pricing service, possibly using a rules engine (e.g., Drools).
- Migrate pricing calculations and promotions to the new service.
- Execute after other services are stable and outside peak seasons.
- Use extensive testing and canary releases.
Output: an independently deployable Pricing service with clear rules.
13. Database Decomposition and Stored Procedure Refactoring (depends on: 3)
Decompose the database and refactor stored procedures. This is a cross-cutting concern that runs alongside service extraction.
Key activities:
- Start with logical separation: create schemas per service and move tables gradually.
- Refactor stored procedures into application code or move them to services.
- Eventually, give each service its own database instance.
- Use CDC and dual-write for data consistency during transition.
- Keep the monolith DB as source of truth until cutover.
Output: a decomposed database with clear data ownership.
14. Reorganize Teams for Independent Deployment (depends on: 1, 2)
Reorganize teams for independent deployment. This step enables long-term autonomy.
Key activities:
- Reorganize teams around services (stream-aligned teams).
- Give each team ownership of its service's repository, CI/CD, and on-call.
- Implement an internal developer platform for self-service deployments.
- Establish service level objectives (SLOs) and error budgets.
Output: autonomous teams that can deploy independently.
15. Post-Migration Optimization and Monolith Decommissioning (depends on: 12)
Optimize after migration and decommission the monolith. This step wraps up the migration.
Key activities:
- After each service extraction, remove dead code from the monolith.
- Gradually reduce the monolith to a smaller core (e.g., back-office).
- Plan eventual decommissioning of monolith components.
- Document learnings and update architecture.
Output: a leaner monolith and a fully service-oriented architecture.
Previous Proposal 3 (ID: 14efa153-1aa1-47b0-9435-75fba2e57cfe, Agent: qwen3.8-flash_initial_3, LLM: alibaba/qwen3.8-flash):
Estimated Complexity: high
Success Metrics: - **Zero Downtime**: Achieve 100% availability of the e-commerce platform throughout the 12 months, including planned maintenance windows.
- **Deployment Independence**: New services can be deployed independently; no code commit forces a full 30-minute monolith downtime. Time-to-deploy for a new service < 5 minutes.
- **Database Decoupling**: Eliminate cross-service SQL joins. The monolith database write load decreases by 90%.
- **Peak Capacity**: System handles 12x traffic load (approx. 480k orders/day) with < 200ms latency at P95 during load tests.
- **Search Latency**: Product availability reflected in search results within < 30 seconds of inventory update (replacing nightly rebuild).
- **Pricing Stability**: 0% deviation in price calculation results between the new architecture and the legacy 'golden master' characterization tests.
Steps (10):
1. Foundation: Infrastructure, Observability, and Safety Net
Before extracting any service, the team must build the 'operating system' for distributed applications. This step focuses on enabling independent deployment and providing real-time visibility into the legacy monolith. The goal is to create a safety net that makes subsequent refactoring steps low-risk and reversible.
* **CI/CD Pipeline**: Implement a dual-track pipeline. The existing monolith gets a 'speedy' pipeline for hotfixes, while a new pipeline infrastructure is set up (e.g., Kubernetes/ECS) ready for independent service deployment.
* **Observability Suite**: Deploy centralized logging (ELK/Loki), metrics (Prometheus/Grafana), and crucially, **Distributed Tracing** (Jaeger/Zipkin). Even within the monolith, we must map request flows to identify coupling.
* **Service Mesh / API Gateway**: Install an API Gateway (e.g., Kong, Nginx ingress) in front of the monolith. This is the 'strangler fig' entry point. All traffic must flow through here. We will use it to route traffic to new services or fallback to the monolith.
* **Feature Flags**: Integrate a feature management system (e.g., LaunchDarkly, Unleash) to decouple deployment from release. This allows us to deploy code that is inactive and test it behind flags.
2. Domain Analysis and Boundary Definition (Strangler Pattern) (depends on: 1)
You cannot extract a service without knowing the domain. With 2M lines and 'unknown' pricing logic, this step is about mapping the terrain. We aim to identify low-risk, high-cohesion boundaries for the first extractions and mark the 'danger zones' (Pricing) for later.
* **Event Storming**: Run workshops with the five teams to map business flows (e.g., 'Checkout', 'Return') and identify command/event boundaries.
* **Code Hotspot Analysis**: Use static analysis tools (e.g., SonarQube, CodeScene) to find files changed together (logical coupling) and complex methods.
* **Dependency Matrix**: Create a matrix showing which database tables are accessed by which application modules. This is critical for the database refactoring later.
* **Service Extraction Plan**: Finalize the order of extraction. Recommended: **Search/Catalogue** (read-heavy, low transactional consistency risk) or **Inventory** (async, distinct boundary). Avoid 'Pricing' initially due to complexity and 'Checkout' until foundational identity is stable.
3. Data Platform Strategy: Outbox Pattern and CDC (depends on: 2)
The 1.2TB PostgreSQL DB with stored procedures is the 'database of doom' for migration. We must stop using cross-module SQL joins. This step introduces a data change capture layer to allow services to communicate via events rather than DB writes.
* **Database Isolation**: Begin identifying tables exclusive to the chosen first domain (e.g., Catalogue tables). Grant strict read-only access to other modules if possible, or refactor code to remove cross-table joins.
* **Change Data Capture (CDC)**: Deploy a tool (e.g., Debezium or Kafka Connect) to stream PostgreSQL WAL logs to a message broker (Kafka/Pulsar). This creates a stream of data changes that can be consumed by other services.
* **Transaction Outbox**: Refactor the monolith code to use an 'Outbox Pattern' for domain events. Instead of just writing to the DB, it also writes a message to an 'Outbox' table in the same transaction. A relay process moves this to Kafka. This ensures 'at least once' delivery and keeps the monolith's transactional integrity while enabling async communication.
4. Extraction of First Service (The 'Read-Only' Pilot) (depends on: 1, 3)
To learn safely, we extract a 'read-only' service with no transactional complexity. The **Product Catalogue/Search** is the best candidate. It is currently Lucene-based, rebuilt nightly. We will move to real-time indexing to improve product freshness.
* **Build the Catalogue Service**: Create a new microservice that owns the Catalogue database tables. It exposes gRPC/REST endpoints for fetching products.
* **Real-time Sync**: The new service subscribes to the CDC events for product changes (from S3). It updates its internal Lucene/Opensearch index in real-time. This eliminates the nightly rebuild and provides immediate search visibility.
* **Dual Read Path**: The monolith code for 'Search' is modified to check a feature flag. If enabled, it calls the new Catalogue Service; otherwise, it uses the old internal Lucene logic.
* **Shadow Traffic**: Use the API Gateway to duplicate live traffic. Send requests to both the monolith and the new service. Compare the responses. Only when error rates are 0% do we flip the feature flag for production traffic.
5. Extraction of Identity and Customer Accounts (depends on: 4)
Next, we extract the **Customer Account** domain. This serves both the storefront and the mobile app. This is a write-heavy domain, requiring careful transaction handling with the legacy monolith during the transition.
* **Service Implementation**: Implement the 'Customer Service' (JWT generation, profile management, authentication). It owns its own database schema (User, Address).
* **Sync with Legacy**: The service publishes 'UserUpdated' and 'UserCreated' events via Outbox/CDC. The monolith listens to these events to keep its local copy of user data synchronized.
* **Strangler Endpoint**: The API Gateway routes '/api/login', '/api/account' traffic directly to the new service. The monolith stops handling these requests. Front-end applications must be updated to handle the new response format (versioning).
* **Database Decoupling**: Over time, remove read access to the monolith's user table for all other domains, forcing them to use the Identity service.
6. Extraction of Inventory Synchronization (depends on: 5)
Inventory is currently updated every 15 minutes via files. This is a bottleneck. We will extract this into a service that integrates directly with the Warehouse Management System (WMS).
* **Inventory Service**: Build a service that consumes warehouse data feeds (replacing the file drop). It updates a centralized stock level view.
* **Event Publishing**: When stock levels change, publish `StockLevelChanged` events to Kafka.
* **Monolith Integration**: Refactor the Cart/Checkout code in the monolith to listen to these events to maintain a local cached view of inventory or to check stock via an API call rather than a SQL join. This removes the 15-minute latency.
* **Consistency Model**: Since inventory is high-concurrency, design a reservation system (Saga) for this service to prepare for the future extraction of Checkout.
7. The 'Black Box' Strategy for Pricing and Promotions (depends on: 6)
The pricing module (200k lines, unknown rules) cannot be rewritten safely from scratch. We treat it as a 'legacy core'. We will wrap it in a service but keep the internal logic untouched in the monolith initially, or isolate it.
* **Characterization Tests**: Write massive integration tests that record the input/output of the pricing module for all 8 countries and 3 currencies. This creates a 'golden master'.
* **Decouple Dependencies**: Refactor the pricing code to rely only on 'Customer', 'Product', and 'Inventory' data fetched via interfaces, not direct DB calls. This prepares it for extraction.
* **Extract as 'Black Box'**: Wrap the existing pricing logic into a new `Pricing Service`. Move the 200k lines of code into this project. It calls a dedicated read-replica database of the pricing tables. This service does not communicate with others directly but is called by the 'Cart' service.
* **Validation**: Run 'shadow mode' traffic against this new service to ensure it matches the golden master before routing any production traffic.
8. Orchestration Layer: Cart and Checkout (The Saga) (depends on: 7)
Checkout is the highest risk. It requires distributed transaction management. We will implement the Cart as a service and the Checkout process as an orchestrator using Sagas.
* **Cart Service**: Extract cart logic into its own stateless/stateful service (Redis-backed). This decouples the browsing experience from the order processing.
* **Checkout Orchestrator**: Build a new 'Order Service' that does not do the work itself but coordinates the process. When a checkout starts, the Order Service begins a **Saga**.
* **Saga Steps**: 1. Validate Pricing (via Pricing Service), 2. Reserve Inventory (via Inventory Service), 3. Authorize Payment (via Payment Service), 4. Create Order Record. If step 3 fails, step 1/2 must be compensated (rollback).
* **Idempotency**: Ensure all services in the saga accept Idempotency Keys to prevent double-charging or double-stock deduction.
9. Extraction of Payments and Order Management (depends on: 8)
Complete the order lifecycle. Move payment integration and order status tracking out of the monolith.
* **Payment Gateway**: Extract the integration with the 3 providers into a `Payment Service`. This service handles webhooks, refunds, and tokenization (PCI scope reduction).
* **Order Management System (OMS)**: Move the database table `orders` and associated history into a new `Order Service`. It consumes the events generated by the Checkout Saga.
* **Back-office Migration**: The back-office (300 staff) is likely server-rendered. Refactor these screens to consume the new `Order Service` APIs. Remove the back-office's direct SQL access to the orders table. This is crucial for reducing load on the monolith DB.
10. Legacy Cleanup and Peak Season Preparation (depends on: 9)
The monolith should now be a 'hollowed-out' shell (mostly just the legacy pricing rules inside a service or a 'legacy' module). We prepare for the peak sales in Jan/July.
* **Database Downsizing**: Detach the schema ownership. The monolith should ideally only connect to a 'read-only' replica for historical data or a small remnant DB.
* **Performance Tuning**: The new architecture is now the single point of failure. Optimize the message broker (Kafka) and API Gateway for 12x traffic.
* **Chaos Engineering**: Run game-days testing resilience. Kill a service (e.g., Search) and ensure the storefront degrades gracefully (shows empty search results but allows cart access).
* **Final Monolith Decommission**: Identify the remaining monolith code. Delete it. If it's just a 'legacy gateway', replace it with pure API routing. The 'Monolith' label should now refer only to the Pricing Service or similar, not a single deployable unit.
Please, considering the previous proposals as ideas that could be considered, focus on the main objective and generate an IMPROVED proposal or a completely DIFFERENT perspective if you deem it appropriate. Only if you consider any of them is amazing and impossible to improve, answer with the same proposal.
The plan has these parts:
- "steps": the list of steps, each with "step_id" (a short label unique within this proposal, such as S1, S2, S3), "title" (a short, descriptive title), "description" (what the step does and how, in Markdown: a short opening paragraph and then, if there are several concrete things to say, a bullet list) and "dependencies" (the step_ids of the other steps of THIS proposal that must be completed first; empty if none).
- "estimated_complexity": "low", "medium" or "high".
- "success_metrics": clear and measurable success metrics, one per line as a bullet list.
Think deeply about the problem, considering all aspects and implications. Develop a comprehensive understanding of what needs to be done to achieve the objective, then produce the plan.
{"steps": [{"step_id": "S1", "title": "Platform Foundation: Kubernetes, CI/CD, and Observability", "description": "Establish the technical foundation for independent service deployment and operation before touching the monolith architecture.\n\n- Provision Kubernetes cluster with dev/staging/prod namespaces, or equivalent managed cloud platform (ECS/App Engine)\n- Deploy centralized logging (ELK or Loki), metrics (Prometheus/Grafana), and distributed tracing (Jaeger)\n- Implement CI/CD pipelines for independent service deployments (GitHub Actions/GitLab CI/ArgoCD)\n- Set up secrets management (Vault) and configuration management (Consul/Spring Cloud Config)\n- Create observability dashboards for: order throughput, latency percentiles (P50/P95/P99), error rates, database load\n- Define SLOs and alerting: order processing latency p99 < 5 seconds, checkout success rate > 99.5%, payment auth speed < 2 seconds", "dependencies": []}, {"step_id": "S2", "title": "Strangler Pattern Setup: API Gateway, Feature Flags, and Service Mesh", "description": "Deploy the infrastructure layer that enables gradual traffic migration from monolith to services without downtime.\n\n- Deploy API gateway (Kong or AWS ALB) in front of monolith; all traffic routes through gateway\n- Implement feature flag system (LaunchDarkly or Unleash) to decouple deployment from traffic routing\n- Set up service mesh (Istio or Linkerd) for inter-service communication, mTLS, and circuit breakers\n- Containerize monolith as-is (Docker) so it can run alongside new services\n- Instrument monolith with event publishing capability: add transactional outbox table for domain events\n- Create blast radius containment: rate limiting, bulkheads, and timeouts at gateway level", "dependencies": ["S1"]}, {"step_id": "S3", "title": "Domain Analysis and Service Boundary Definition via Event Storming", "description": "Map the monolith's business domains and dependencies to identify safe extraction sequence and service boundaries.\n\n- Run event storming workshops with all five teams; map customer journeys (Browse → Cart → Checkout → Order → Fulfillment → Returns)\n- Create dependency matrix: which tables, stored procedures, and methods are accessed by each domain\n- Use code hotspot analysis (SonarQube, CodeScene) to find logical coupling and identify decoupling opportunities\n- Define service extraction sequence based on coupling and business risk: prioritize read-heavy (Search), well-bounded (Inventory), and identity (Customer) over complex (Pricing, Checkout)\n- Document all cross-module joins; mark which ones must be eliminated vs. which can tolerate eventual consistency\n- Identify stored procedures that span multiple domains; plan refactoring or replication strategy", "dependencies": ["S2"]}, {"step_id": "S4", "title": "Peak Season Protection Framework and Change Freeze Calendar", "description": "Establish hard boundaries to protect January and July sales from destabilizing changes.\n\n- Map annual peak periods: January sales (peak revenue), July sales, plus promotional events\n- Define 6-week freeze windows: 4 weeks before + 2 weeks during each peak season; no major extractions or refactors during freeze\n- Identify lowest-risk windows in each month for incremental changes (hotfixes, small extractions, data migrations only)\n- Create rollback runbooks for every step: how to revert traffic routing, database changes, and service deployments in < 30 minutes\n- Establish incident escalation and communication plan: business owners notified of any changes near peak season\n- Plan load testing outside freeze windows: validate 12x capacity (480k orders/day) for each service before peak season", "dependencies": ["S3"]}, {"step_id": "S5", "title": "Pricing Module Characterization: Black Box Baseline and Test Suite", "description": "Thoroughly document the 200k LOC pricing engine behavior before any extraction attempt, eliminating unknown risk.\n\n- Analyze and document all pricing rules: country-specific logic, currency handling, promotional rules, edge cases\n- Create comprehensive characterization test suite: record input/output for all 8 countries × 3 currencies × major promotional scenarios\n- This test suite becomes the 'golden master': any new pricing service must match 100% of outputs\n- Build test data set covering: normal pricing, discounts, bulk pricing, regional pricing, multi-currency edge cases, seasonal promotions\n- Document all dependencies: which customer attributes, product attributes, inventory levels, and time-based factors affect pricing\n- Establish CI gate: pricing service extraction cannot proceed until characterization tests pass 100%", "dependencies": ["S3"]}, {"step_id": "S6", "title": "Test Coverage Improvement: Target 70% for Extract-Candidate Modules", "description": "Increase test confidence for modules scheduled for early extraction; reduce rollback risk from test blindness.\n\n- Audit current test coverage by module; identify gaps in: Search, Catalogue, Inventory, Cart, Customer\n- Implement integration tests for critical flows: order creation, payment processing, inventory updates, customer account creation\n- Add contract tests (Pact) between modules to catch API breaking changes early\n- Use mutation testing to verify test quality: tests must catch injected bugs\n- Target 70%+ coverage for Search, Inventory, Customer, Cart, Payments modules\n- Establish automated quality gates: no service extraction if module coverage < 60%; no production deployment if < 70%\n- Create load test suites for peak scenarios: simulate 40k→480k order escalation for each module", "dependencies": ["S3"]}, {"step_id": "S7", "title": "Change Data Capture and Event-Driven Data Sync Infrastructure", "description": "Build the plumbing to eliminate cross-module database joins and enable eventual consistency between services.\n\n- Deploy CDC tool (Debezium with Kafka/Pulsar) to stream PostgreSQL WAL changes to message broker\n- Refactor monolith to use transactional outbox pattern: all domain events written atomically in same transaction as business data\n- Create event schema versioning: events must be backwards/forwards compatible as services evolve\n- Implement dual-write mechanism: during transition, write to both monolith database and new service database\n- Set up event relay: monolith publishes events (OrderPlaced, PaymentAuthorized, InventoryReserved) to Kafka\n- Define eventual consistency model: which operations can tolerate delayed propagation vs. which require immediate consistency", "dependencies": ["S2", "S5"]}, {"step_id": "S8", "title": "Search and Catalogue Service Extraction: Read-Heavy Pilot Service", "description": "Extract the first service: read-heavy, low transactional risk, validates the entire strangler fig pattern.\n\n- Build new Catalogue and Search service: REST API for product lookup, search, and filtering\n- Create new database schema (PostgreSQL): product data, categories, attributes; use Elasticsearch/OpenSearch for real-time search indexing\n- Subscribe to CDC events from monolith: ProductUpdated events trigger real-time search index refresh (eliminates nightly Lucene rebuild, improves freshness to < 1 minute)\n- Implement dual-read path: feature flag controls whether requests hit monolith Lucene or new Search service\n- Use API gateway shadow traffic: send requests to both old and new service; compare responses; alert on differences\n- Gradually shift traffic: 10% → 25% → 50% → 100% using feature flags and canary deployments\n- Maintain dual-write for 2 weeks post-cutover to verify correctness; then deprecate monolith search code", "dependencies": ["S6", "S7"]}, {"step_id": "S9", "title": "Inventory Service Extraction: Real-Time Warehouse Synchronization", "description": "Extract inventory as second service: async boundary, directly integrates with warehouse system, eliminates 15-minute sync latency.\n\n- Build Inventory service: consumes warehouse file feed (SFTP/API) directly instead of monolith polling\n- Create inventory database schema: stock levels, reservations, holds per product per location\n- Publish inventory events: StockLevelChanged, ReservationCreated, ReservationReleased to Kafka\n- Implement reservation system (prepare for saga pattern): inventory holds items during checkout, releases on order confirmation or timeout\n- Dual-write monolith inventory data during transition: maintain consistency between old and new\n- Test warehouse sync at peak load: ensure 15-minute sync windows do not slip under 480k daily orders\n- Validate that all cart and checkout code calls inventory service via API (or consumes events) rather than direct SQL join\n- Gradual traffic shift: test with non-critical inventory queries first, then critical paths", "dependencies": ["S7", "S8"]}, {"step_id": "S10", "title": "Customer and Loyalty Service Extraction: Identity Decoupling", "description": "Extract customer accounts and loyalty programs: enables independent auth scaling and multi-tenant loyalty rules.\n\n- Build Customer service: JWT token generation, profile management, address management, identity verification\n- Create customer database schema (separate from monolith): User, Address, Profile; replicate to read-only cache where needed\n- Implement loyalty points service: handles country-specific loyalty rules (8 countries, different point accrual rates)\n- Sync customer data via events: monolith publishes CustomerCreated, CustomerUpdated, CustomerDeleted to Kafka\n- API gateway routes: /api/login, /api/profile, /api/loyalty to new Customer service; monolith drops these endpoints\n- Ensure backwards compatibility: versioned API responses so old mobile app clients still work\n- Test at peak concurrency: concurrent logins, loyalty point updates under 480k orders/day load\n- Implement session management: distributed sessions (Redis-backed) so users stay logged in during monolith↔service transitions", "dependencies": ["S9"]}, {"step_id": "S11", "title": "Saga Pattern Framework and Distributed Transaction Orchestration", "description": "Implement the orchestration layer required for multi-service transactions before extracting payment and order services.\n\n- Build saga pattern library: support both choreography (event-driven) and orchestration (centralized coordinator) patterns\n- Implement compensating transactions: if payment fails during checkout, inventory reservation and pricing calc must roll back\n- Add idempotency framework: all services accept idempotency-key headers; prevent duplicate charges, double-deductions\n- Handle timeouts and retries: exponential backoff, circuit breakers, manual intervention for stuck sagas\n- Create saga log: record saga execution with state transitions for auditing, debugging, and replay\n- Test saga execution under peak load and network failures: simulate payment provider latency, inventory service timeouts\n- Document saga flows: checkout saga (price → reserve inventory → authorize payment → create order), return saga, refund saga\n- Implement distributed tracing: each saga step is traced end-to-end for observability", "dependencies": ["S7"]}, {"step_id": "S12", "title": "Payment Service Extraction: PCI-Scoped and Secure", "description": "Extract payment processing with extreme security rigor: handles card data, three payment providers, regulatory compliance.\n\n- Build Payment service: integration with all three payment providers (tokenization, authorization, capture, refund)\n- Implement PCI-DSS compliance: no raw card data in logs, encrypted transport, minimal data exposure in monolith\n- Handle payment declines and fraud: integrate fraud detection, implement retry logic for transient failures\n- Create idempotent payment requests: prevent double-charging if client retries or network fails mid-request\n- Implement webhook handling: payment providers notify service of async events (captures, chargebacks, refunds)\n- Design rollback procedure: if new service fails catastrophically, fall back to direct monolith payment handling (via feature flag)\n- Load test: 500+ payments/sec at peak (baseline 40k orders/day → 480k orders/day = ~550 payments/sec)\n- Test all three provider scenarios: happy path, declines, timeouts, chargebacks", "dependencies": ["S11"]}, {"step_id": "S13", "title": "Orders Service Extraction: Orchestrator for Checkout and Fulfillment", "description": "Extract order management: central service coordinating checkout saga and order lifecycle across all services.\n\n- Build Order service: order creation, status tracking, order querying API for all business users (inventory, fulfillment, customer service teams)\n- Implement checkout orchestrator: accepts cart (items, customer, delivery address) → triggers saga → creates order record on success\n- Integrate with Payment service (authorize payment), Inventory service (reserve stock), Pricing service (calculate total), Customer service (loyalty points)\n- Implement order state machine: validate state transitions (Pending → Confirmed → Shipped → Delivered), prevent invalid transitions\n- Create order event stream: OrderCreated, PaymentAuthorized, InventoryReserved, OrderConfirmed, OrderShipped for other services to consume\n- Use event sourcing: maintain immutable log of all order state changes for audit trail and replay capability\n- Test concurrent order processing at peak load: 40k→480k orders/day; ensure no race conditions, duplicate orders, or lost transactions\n- API design: query orders by customer ID, order ID, SKU, date range; sorting and filtering for back-office use", "dependencies": ["S12"]}, {"step_id": "S14", "title": "Cart Service Extraction: Stateful Session Management", "description": "Extract shopping cart as stateful service: decouples browsing/cart operations from order processing, independent scaling.\n\n- Build Cart service: add/remove items, update quantities, persist session state, apply coupons/discounts\n- Implement cart storage: Redis for session-backed stateless carts, or PostgreSQL with session affinity for persistent carts\n- Integration with services: calls Catalogue service (product availability), Inventory service (stock check), Pricing service (cart totals)\n- API design: cart operations (add/remove/view), subtotals with pricing breakdowns, coupon application\n- Implement session stickiness: API gateway routes same user to same Cart service instance (or share Redis state)\n- Test at peak concurrency: concurrent cart updates from same user (one browser tab → mobile app → browser again)\n- Ensure idempotency: adding same item twice returns same cart state, no duplicates\n- Gradual traffic shift: test with non-critical users first, then ramp up", "dependencies": ["S10"]}, {"step_id": "S15", "title": "Pricing Service Extraction: Black Box Wrapping and Golden Master Validation", "description": "Extract pricing logic as black box service using characterization tests to ensure 100% correctness preservation.\n\n- Move 200k LOC pricing logic into dedicated Pricing service with own codebase\n- Service exposes API: accepts product IDs, customer attributes, location, time, inventory levels → returns price, applicable promotions, currency\n- Use dedicated read-replica database with pricing tables only (no cross-joins to other domains)\n- Run shadow mode traffic: send live pricing requests to both old monolith and new service; compare outputs; alert on any divergence\n- Validation gate: pricing service must match characterization test suite 100% for all 8 countries, 3 currencies, all tested scenarios\n- Feature flag control: gradually shift production traffic once shadow mode validates correctness\n- Document decision: this service remains a black box (we don't refactor internal logic); future teams can safely extend without fear\n- Plan Phase 2 refactoring separately: after service is stable in production, optionally decompose into rules engine (Drools) in future quarter", "dependencies": ["S5", "S13"]}, {"step_id": "S16", "title": "Returns Service Extraction and Order Lifecycle Completion", "description": "Extract returns handling: completes order lifecycle, depends on Orders and Pricing services being stable.\n\n- Build Returns service: process return requests, validate return eligibility, calculate refunds (using Pricing service), manage return shipping\n- Integrate with Orders service: fetch order data, verify items purchased\n- Integrate with Inventory service: return items to stock after confirmation\n- Integrate with Payment service: process refunds back to original payment method\n- API design: create return request, track return status, generate return shipping labels\n- Implement return state machine: Requested → Approved → Shipped → Received → Refunded\n- Consumer integration: back-office staff (or customer self-service) calls Returns service APIs instead of monolith\n- Test return flows at peak load: validate no inventory/refund race conditions", "dependencies": ["S13", "S15"]}, {"step_id": "S17", "title": "Back-Office Service Aggregation and Staff User Experience", "description": "Update back-office (300 staff) to consume new service APIs; eliminate monolith direct database access.\n\n- Create service aggregation endpoints: orders endpoint calls Order + Payment + Inventory + Shipping services; returns endpoint calls Returns service\n- Implement API gateway service discovery: back-office transparently calls services even if they move/scale\n- Add caching layer: frequently accessed data (customer profiles, order lists) cached with TTL to reduce service latency\n- Implement timeouts and graceful degradation: if one service is slow, show cached data or partial results\n- Refactor back-office UI: replace monolith SQL queries with REST API calls\n- Test with 300 concurrent staff users: search across orders/customers, filtering by date/status, bulk actions\n- Implement distributed tracing: back-office requests are traced across all services for debugging\n- Add retry logic: transient failures (network blips) automatically retry; permanent failures show user-friendly errors", "dependencies": ["S13", "S16"]}, {"step_id": "S18", "title": "Load Testing and Peak Capacity Validation Across Full System", "description": "Validate new distributed architecture handles peak load (480k orders/day) without degradation; stress test before peak seasons.\n\n- Simulate realistic peak load: 480k orders/day (12x baseline), 8 countries, 3 currencies, 4 languages simultaneously\n- Test sequence: base load → ramp to 480k → sustain for 30 minutes → spike to 1.5x peak → graceful degradation\n- Measure latencies: checkout flow (cart → confirmation) p95 < 5 seconds, payment authorization < 2 seconds, search < 1 second\n- Monitor service-level metrics: requests/sec, error rates, database query times, message broker throughput, cache hit rates\n- Identify and optimize bottlenecks: pricing calculations, search queries, payment provider round-trip time, inventory reservations\n- Test database connection pools: ensure no exhaustion or deadlocks under peak load\n- Validate message broker (Kafka): 480k messages/day throughput, latency, durability\n- Create realistic user behavior: product browsing → search → add to cart → checkout flows, not just load\n- Fail-over testing: kill one service (e.g., Search); verify system degrades gracefully, no cascading failures\n- Load test outside freeze windows; complete before January/July peak seasons", "dependencies": ["S17"]}, {"step_id": "S19", "title": "Team Reorganization and Independent Deployment Readiness", "description": "Reorganize teams around services to enable independent deployments and long-term operational autonomy.\n\n- Reorganize five teams: from business-function-based (Pricing team, Fulfillment team) to stream-aligned (Search Service team, Orders Service team)\n- Assign service ownership: each team owns their service's codebase, CI/CD pipeline, database schema, on-call rotation, SLOs\n- Implement internal developer platform (IDP): golden path templates, self-service deployments, secrets rotation, observability dashboards\n- Establish SLOs per service: error budget, latency targets, availability targets\n- Create cross-team API contracts: service teams sign off on API changes; breaking changes trigger communication plan\n- Set up inter-service communication: API versioning, deprecation periods, backward compatibility requirements\n- Plan on-call: each team on-call for their service; pager rotation, incident response training\n- Document service dependencies: which services call which; upstream/downstream impact analysis", "dependencies": ["S18"]}, {"step_id": "S20", "title": "Monolith Decommissioning and Legacy Code Cleanup", "description": "Safely retire monolith code once all services are stable and production-proven.\n\n- Audit monolith codebase: identify dead code (Search, Catalogue, Inventory, Customer, Orders, Payments, Cart, Returns logic)\n- Delete extracted service code from monolith; remove dual-write logic once service has proven stable (30+ days in production)\n- Gradually reduce monolith database: archive or migrate old tables, remove cross-module stored procedures\n- Plan monolith decommissioning: if monolith becomes shell (mostly unused), decide: keep as fallback or shut down completely\n- Maintain 90-day read-only archive of monolith database for emergency historical queries and regulatory retention\n- Update backup/recovery procedures: shift from single monolith snapshot to per-service snapshots\n- Document architectural decisions: why services were split this way, what problems were solved, what trade-offs were made\n- Create incident playbooks: common failure modes, resolution steps, escalation paths\n- Close out migration project: update runbooks, retire temporary monitoring, establish steady-state operational procedures\n- Celebrate: migration complete, new architecture proven at peak load, five teams deploying independently", "dependencies": ["S19"]}], "estimated_complexity": "high", "success_metrics": "- Zero unplanned downtime during 12-month migration; all maintenance windows scheduled and communicated; zero production incidents caused by migration\n- Peak seasons (January and July sales) proceed with zero degradation: 480k orders/day processed with p95 checkout latency < 5 seconds, payment authorization < 2 seconds, zero payment processing failures\n- All eight services independently deployable: no code commits force monolith downtime; new service deployment < 5 minutes; deployment frequency increases from bi-weekly (monolith) to daily (services) where applicable\n- Test coverage increased from 25% to 70%+ for all extracted services (Search, Inventory, Customer, Cart, Orders, Payments, Returns); characterization test suite for Pricing passes 100% before service extraction\n- Every service deployment is rollback-able in < 30 minutes: documented procedures tested monthly; rollback automated where possible\n- Data consistency validated: monthly reconciliation between service databases and monolith shows zero inconsistencies; dual-write period completes successfully (2 weeks per service)\n- Order processing SLA maintained: cart → confirmation latency unchanged or improved; maintained under 5 seconds at peak load (480k orders/day)\n- All five teams deploying independently by month 12: no cross-team deployment coordination required; each team owns service, deployment pipeline, on-call rotation\n- Search latency improved or maintained: product availability reflected in search results within < 1 minute of inventory update (vs. previous nightly rebuild), baseline latency unchanged\n- Inventory synchronization preserved: no missed 15-minute warehouse sync cycles during migration; 100% of daily inventory updates processed\n- Back-office operations unaffected: 300 staff members seamlessly using new service APIs; service aggregation endpoints maintain < 500ms p95 latency\n- Payment processing: zero regressions with all three payment providers; fraud detection remains active; PCI-DSS compliance maintained; idempotency prevents duplicate charges\n- Event-driven architecture validated: Kafka message broker handles 480k messages/day at peak; no message loss or ordering violations\n- Rollback capability proven: every step validated to be reversible; no permanent cutover without 30-day validation period and green light from peak season calendar"}This proposal transformed from a generic template into a highly rigorous, constraint-driven execution plan. It explicitly tackled the hardest constraints by introducing a scope ladder, a rollback charter, and a four-stage cutover playbook. It correctly abandoned the unrealistic goal of blanket test coverage in favor of seam-level verification.
- Introduced a strict peak-aware calendar, scope ladder, and rollback charter to enforce constraints.
- Replaced blanket test coverage with seam-level verification using golden masters and shadow diffing.
- Defined a reusable four-stage cutover playbook with reverse CDC for genuine reversibility.
- Added executable architecture enforcement using ArchUnit and SQL linters to prevent re-coupling.
- The 18 steps are dense and might be overwhelming for a quick read.
- Team reorganization is implied but less explicitly detailed as a standalone step compared to Proposal 1.
- Proposal 1 : Peak-season protection framework, shadow traffic with checksum comparison, and keeping read-only access post-cutover.
- Proposal 3 : CDC via Debezium with transactional outbox, golden master for pricing, and real-time catalogue indexing.
- Proposal 1 : Raising test coverage to 70%, refactoring pricing rules into a DSL, and decommissioning the legacy database early.
- Proposal 3 : Moving pricing to a new project while reading a replica, placing checkout before payment, and lacking a month-by-month calendar.
+ Program setup, peak-aware calendar, rollback charter and scope ladder+ Executable architecture map, table ownership and boundary enforcement+ Delivery platform: per-module pipelines, gateway, feature flags, environments+ Observability, business SLOs, error budgets and the automated rollback controller+ Split the deployment unit and retire the 30-minute maintenance window+ Seam-level verification: golden master, contracts, shadow diffing, reconciliation+ Data platform: schema ownership, join elimination, CDC, outbox, four-stage cutover playbook+ Extract Returns as the first write-path and own-database proof+ Extract Inventory and replace the 15-minute warehouse file exchange+ Extract Payment under a stricter regime than anything else+ Extract Order Management with an explicit state machine+ Compose Checkout from independent services using a saga+ Migrate back-office, storefront and mobile clients off the monolith database+ Decommission the monolith core and harden for the second peakMobilize Program and Define Target ArchitectureBuild Platform Foundation for Independent DeploymentsImplement Strangler Fig Facade and Monolith InstrumentationEstablish Continuous Delivery and Test AutomationExtract Inventory ServiceExtract Returns ServicePeak Season Readiness and Resilience EngineeringExtract Order Management and Checkout OrchestrationDatabase Decomposition and Stored Procedure RefactoringReorganize Teams for Independent DeploymentPost-Migration Optimization and Monolith Decommissioning
The plan produced
1. Program setup, peak-aware calendar, rollback charter and scope ladder new
Turns the brief's constraints into an operating rhythm that everything later obeys. The binding constraint in this objective is the calendar, not the technology, so the calendar is decided first.
- Run a two-week inception to baseline the current state: build time, deployment lead time, change failure rate, MTTR, MTTR, per-module change frequency, database load profile. Progress must be measurable, not asserted.
- Declare hard freezes from 1 December to 15 January and 1 June to 15 July. During a freeze only rollback-enabling and hardening changes are allowed.
- Confirm the two open delivery windows of the year (roughly February–May and August–November) and accept in writing that only these windows carry migration increments.
- Set the soak rule: no change on the checkout path lands within four weeks of a freeze; anything that would violate it is deferred to the next window.
- Define the peak-readiness gate that runs six weeks before each peak: 12x load test, capacity headroom check, rollback rehearsal, error-budget review. The gate is pass/fail and its evidence is published.
- Write the rollback charter: every increment ships an expand/contract database change, a feature-flag kill switch, and a rehearsal recorded in a game day. No go-live without a rehearsed rollback.
- Publish the scope ladder: a ranked list where rungs 1–6 deliver the core objective and rungs 7+ are optional. Slippage means stopping at a rung boundary, never mid-increment.
- Set the capacity budget at 40–50% of the five teams' capacity for migration alongside normal feature work, and staff the ladder to fit that budget rather than to fill the year.
- Create a migration enablement squad of six engineers drawn on rotation from the five teams. It owns the platform, the shared cuts and the risky shared data work.
2. Executable architecture map, table ownership and boundary enforcement (after 1) new
Produces an architecture map that the build itself enforces. Five teams committing to one repository will silently re-couple anything that is separated and not policed, so enforcement is part of the map, not a later step.
- Instrument the monolith with distributed tracing and let it run four weeks. Real call paths beat static imports for finding true coupling.
- Build a table-to-module and query-to-module map by parsing every SQL statement, ORM mapping and stored procedure in the codebase, cross-checked against the database's own query logs.
- Score each candidate service on four axes: coupling, transactional risk, change frequency and peak-path criticality. This ranking, not intuition, drives the extraction order.
- Assign every one of the 350 tables to exactly one owning module. Tables nobody can own are declared contested and scheduled into the data work of S7.
- Add ArchUnit rules to CI that fail the build on any new cross-module Java dependency, with existing violations frozen into a baseline file that may only shrink.
- Add a SQL linter to CI that fails on cross-module joins and cross-module writes, with the same shrinking baseline.
- Publish the target service list, the owning team per service, and the reasoning as architecture decision records.
- Hold a mid-program review at month six to re-rank the scope ladder using what the map actually showed. This is the one planned re-planning point of the program.
3. Delivery platform: per-module pipelines, gateway, feature flags, environments (after 1, 2) new
Builds the delivery and traffic machinery that makes every later step reversible. No module is extracted until its team can deploy, flag and route on its own.
- Extend the platform foundation on Kubernetes (or the existing container platform if one exists) with one namespace per service, quotas and autoscaling policies sized for a 12x peak.
- Put an API gateway in front of the monolith as the strangler entry point. Storefront, mobile and back-office traffic all flow through it from day one, even while it routes everything to the monolith.
- Give every module its own CI/CD pipeline and its own environment. The monolith keeps its current pipeline for hotfixes until S5 replaces it.
- Deploy a feature-flag service and require every new call path to be flag-guarded. Flags are the primary rollback instrument for the whole program.
- Introduce secrets management and per-environment configuration so changing behaviour never requires a monolith redeploy.
- Define golden-path templates for a new service: build, pipeline, observability, health checks, flag integration, database migration tool. Extraction must not start from a blank page.
- Reserve two permanent environments: a full-size production-like soak environment and a load-test environment capable of generating 12x traffic against production-shaped data.
4. Observability, business SLOs, error budgets and the automated rollback controller (after 3) new
Makes the system observable enough that a canary is judged automatically and reverted without a human guessing. This is the prerequisite for the rollback promise made in every later step.
- Deploy centralized logging, metrics and distributed tracing, with trace correlation working across the gateway, the monolith and every new service from the start.
- Instrument the monolith's blind spots: query latency by module, connection-pool saturation, Lucene rebuild duration, warehouse file-exchange lag.
- Define SLOs on business outcomes, not infrastructure: checkout success rate, order confirmation p99, search latency, payment authorisation rate, price computation latency, warehouse sync freshness.
- Attach an error budget to each SLO and write the policy: when a service burns budget, its rollout stops automatically and its flags revert. No negotiation during a peak.
- Build the rollback controller: on error-rate or latency divergence beyond threshold during a canary, the gateway shifts traffic back and flags are disabled without human action.
- Create per-service dashboards a tired engineer can read at 03:00, plus one program dashboard showing progress against the scope ladder.
5. Split the deployment unit and retire the 30-minute maintenance window (after 2, 3) new
Delivers the objective's headline — independently deployable units — before any process separation, by splitting the build and the release train while the code still runs together. This is the cheapest large win available and it removes the maintenance window.
- Split the single artefact into one build per owning module with a shared parent, so a module can be built, tested and released on its own.
- Allow modules to be released as separate artefacts on the existing runtime first. Independent deployability is a build and release property long before it is a topology property.
- Retire the two-week coordinated release train. Each team gets its own pipeline, cadence and on-call rota, with the gateway and schema compatibility as the contract between teams.
- Adopt expand/contract database migrations so schema and code changes no longer have to ship together.
- Replace the maintenance window with blue-green deployment on two identical stacks, traffic switched at the gateway and rollback performed by switching back.
- Measure and publish the result: deployment lead time, deployment frequency per team, and the share of releases that needed no coordination with another team.
6. Seam-level verification: golden master, contracts, shadow diffing, reconciliation (after 2, 3) new
Replaces the impossible goal of blanket test coverage with verification exactly where the cut will be made. A two-million-line monolith cannot reach 70% coverage in a year; a service boundary can be verified to a very high standard in weeks.
- Build a characterization harness that records real production requests and replays them against the monolith, capturing full responses as a golden master. This is the safety net for every extraction.
- Require every extracted service to pass the golden master on its public API before it takes live traffic, producing a diff report rather than a pass/fail.
- Use consumer-driven contract tests between the monolith and each new service, and between services, so a change on one side breaks a build instead of production.
- Run shadow traffic: mirror live requests to the new service, compare responses field by field, and gate the traffic ramp on the divergence rate.
- Build per-module data reconciliation as a first-class test: row counts, checksums and business invariants compared on a schedule, with an owner and an alert threshold.
- Add synthetic canary transactions that execute a real checkout, return and search every few minutes and alert on functional regression before customers notice.
- Explicitly do not pursue blanket line coverage of the monolith. Track coverage only for newly written service code, where the target is 80%.
7. Data platform: schema ownership, join elimination, CDC, outbox, four-stage cutover playbook (after 2, 3, 6) new
The hardest part of the program and the part most plans under-specify. It does not depend on service extraction, so it starts in month one and runs in parallel with everything else.
- Enforce ownership inside the database itself: one PostgreSQL role per module, able to write only its own schema and to read others only through defined views. Cross-schema writes are rejected by the database, not by convention.
- Inventory every stored procedure, attribute it to one module, and either move it into that module's code or leave it as a module-private function. After a module is extracted, no stored procedure may touch two modules' tables.
- Eliminate cross-module joins one at a time, replacing each with an API call, an event-fed materialized read model or a duplicated read-only projection. Track the count per module and drive it to zero before that module is cut.
- Stand up change data capture with Debezium reading the PostgreSQL WAL into Kafka. This publishes monolith domain events with no application change, the lowest-risk start available.
- Add a transactional outbox for new services so their events and their state changes commit together.
- Adopt one reusable four-stage cutover playbook per module and apply it identically every time. Stage A: the service owns its schema logically, reads from CDC into its own store, and serves shadow traffic only. Stage B: reads cut over, the monolith stays system of record. Stage C: writes cut over, and the monolith's tables become read-only replicas fed by reverse CDC from the service. Stage D: old tables and dead code are dropped only after a full peak or four clean weeks, whichever is longer.
- Make stage C genuinely reversible: because the sync direction can be flipped, rolling back a write cutover is a configuration change plus a reconciliation pass, not a data restore.
- Build the reconciliation service now so every later cutover has an objective consistency check with thresholds and owners.
- Schedule the 1.2 TB storage migration as background work: new services start on the existing cluster with their own schemas, and physical split happens only once a module is stable.
8. Extract Catalog and Search (after 5, 6, 7)
First extraction, chosen because it is read-heavy, mostly isolated and carries no transactional risk. It also pays for itself: replacing the nightly Lucene rebuild with real-time indexing is a visible business win that buys political cover for the harder cuts.
- Create a Catalog service owning product, category and media tables plus its own search index.
- Feed it from CDC so product and price changes appear in search within seconds instead of after a nightly rebuild.
- Route through the gateway behind a flag and ramp 1% → 5% → 25% → 50% → 100%, with the rollback controller able to revert to the monolith's internal Lucene path at any point.
- Run shadow traffic and compare result sets before any live traffic, then keep the old index warm for two weeks after full cutover.
- Verify the mobile app, which hits the same endpoints, inside the same ramp; its behaviour is part of the go/no-go.
- Land this cut in an open delivery window and let it soak at least four weeks before the freeze.
9. Extract Returns as the first write-path and own-database proof (after 5, 6, 7) new
Second extraction and the first that owns writes and a database. Returns is chosen because it is off the peak-critical path, has modest coupling, and exercises the full four-stage playbook at low stakes.
- Build the Returns service with its own schema, consuming order and customer events rather than joining their tables.
- Run the playbook end to end: shadow reads, read cutover, then write cutover with reverse CDC keeping the monolith's tables current.
- Prove the rollback path in a game day before write cutover, including a reconciliation pass and a re-run of the golden master.
- Keep the back-office returns screens on the monolith for now, so staff workflow is untouched by this step.
- Record every friction point and correct the playbook. The real output of this step is a proven, reusable procedure, not just one service.
10. Extract Inventory and replace the 15-minute warehouse file exchange (after 5, 6, 7) new
Removes one of the sharpest coupling points in the system and unblocks the checkout work. Inventory is extracted in parallel with the other early cuts because it couples the monolith to an external warehouse process rather than to other modules.
- Build the Inventory service to ingest the warehouse feed directly and publish stock-level events.
- Preserve the existing file-based interface for the first weeks, running the new ingest in parallel with the legacy feed and reconciling hourly until they agree.
- Keep the monolith's inventory tables as a projection fed by events, so cart and checkout keep working unchanged during the cut.
- Design reservation semantics now — reserve, confirm, release, with expiry — even though checkout is not yet extracted. The API is needed later and is cheap to get right here.
- Load-test inventory ingest at 12x, because the warehouse feed schedule and the sales peaks do not always coincide.
- Cut over reads first, then writes, with the rollback controller able to restore the file feed as the source of truth.
11. Extract Customer Accounts and Loyalty, with a conservative auth strategy (after 5, 6, 7, 9)
Extracts customer accounts and loyalty, including the authentication decision. Auth is the step that most often derails e-commerce migrations, so the auth path is deliberately moved last and guarded hardest.
- Build the Customer service owning profile, address and loyalty tables, with country-specific loyalty rules expressed as data where possible and as code where not.
- Keep authentication in the monolith for the first phase. Move token issuance only once customer data is stable, and never within four weeks of a freeze.
- Introduce distributed session handling and a token-validation API so services can verify identity without querying the monolith database.
- Cut over reads, then writes, with reverse CDC, validating against the golden master across all 8 countries and 4 languages.
- Verify the mobile app's session behaviour explicitly, since it holds long-lived sessions the storefront does not.
- Move loyalty point accrual and redemption last, because a loyalty error is a customer-visible financial error, not a technical incident.
12. Extract Cart (after 8, 10, 11)
Extracts the cart, which is stateful and sits directly in front of checkout. It is done before pricing and checkout because both need a stable cart boundary to call.
- Build the Cart service on Redis for session and line-item state, validating products and inventory through service calls rather than database joins.
- Make every cart operation idempotent, because a retried add or remove during a peak must not duplicate a line item.
- Keep the cart tables in the monolith as a read-only projection fed by events, for rollback and for the not-yet-migrated back-office screens.
- Ramp traffic while monitoring cart abandonment rate as the business metric, since cart latency shows up as lost revenue rather than as errors.
- Exercise anonymous and authenticated carts separately; they follow different paths and fail in different ways.
- Land this cut in an open window with a full four-week soak before the freeze.
13. Extract Pricing and Promotions as an unchanged black box (after 5, 6, 7)
Extracts the 200,000-line pricing module without rewriting it. The rules are not understood by anyone, so they are wrapped and characterized rather than reverse-engineered. Rule decomposition, documentation and a DSL are explicitly out of scope for these twelve months.
- Build a golden master corpus from at least a million real historical pricing requests and their recorded outputs, covering all 8 countries, 3 currencies and 4 languages, plus every promotion type that can be discovered.
- Refactor only the module's dependencies: pricing must obtain customer, product and inventory data through interfaces rather than direct database access, so it can be lifted out.
- Move the pricing code into its own service unchanged, owning its tables after cutover, and expose a single decision API.
- Run it in shadow mode for at least four weeks against live traffic, comparing every computed price with the monolith. Any divergence blocks the ramp.
- Cut over behind a flag with per-country ramps, since a pricing error is a financial and legal exposure rather than a technical incident.
- Keep the in-monolith evaluator available and warm as the rollback path for at least one full peak after cutover.
- State in writing that rule decomposition is deferred to a follow-up program, so it does not creep back into this one.
14. Extract Payment under a stricter regime than anything else (after 5, 6, 7) new
Extracts payment processing, where mistakes are irreversible and regulatory. Payment is done before checkout orchestration, because checkout cannot be decomposed without a payment boundary already in place.
- Build the Payment service owning the integration with the three providers, including tokenization, authorisation, capture, refund and provider webhooks.
- Reduce PCI scope rather than expand it: no raw card data at rest in the new service, credentials in secrets management, no card data in logs or traces.
- Make every payment operation idempotent with explicit idempotency keys, because retries at peak are normal and double charges are not recoverable.
- Cut over provider by provider rather than all three at once, starting with the lowest-volume provider.
- Run the golden master across all decline, timeout, partial-authorisation and refund scenarios, and rehearse the fallback to the monolith's direct provider integration.
- Verify fraud detection and 3-D Secure paths explicitly, since they are usually the least covered and the most visible when they break.
- Land this cut early in an open window so it soaks well before the freeze.
15. Extract Order Management with an explicit state machine (after 9, 10, 13, 14) new
Extracts order management as the record of truth for the order lifecycle, after the services it depends on exist and are stable.
- Build the Order service with its own database and an explicit order state machine that validates every transition.
- Introduce event sourcing for order status so the audit trail satisfies regulators and fulfilment teams, and so state can be rebuilt after an incident.
- Consume events from payment, inventory and returns rather than polling or joining.
- Cut over reads first for the five teams that query orders, then writes, keeping the monolith's order tables as a reverse-CDC projection.
- Reconcile order counts and monetary totals hourly against the monolith throughout the transition. A monetary mismatch is an immediate rollback, not a ticket.
- Load-test concurrent order state transitions at peak, since the state machine becomes the new serialisation point.
16. Compose Checkout from independent services using a saga (after 12, 13, 14, 15) new
The highest-risk cut in the program, deliberately placed last among the transactional work and only after the components it orchestrates are individually proven.
- Build an orchestrating Checkout service that performs: cart validation, price computation, inventory reservation, payment authorisation, order creation.
- Implement compensating actions for every step: a failed authorisation releases the inventory reservation; a failed order creation voids the authorisation.
- Require idempotency keys end to end so a retried checkout cannot double-charge or double-reserve.
- Handle timeouts explicitly, including the peak case where inventory or pricing is slow. The saga must fail safe to a retryable state, never to a half-committed order.
- Mirror live checkout traffic to the new orchestration and compare full outcomes, including order totals and reservations, before any live traffic.
- Ramp live traffic during an open window only, and keep the monolith's checkout path fully functional and warm for rollback until it has survived a peak.
- Hold the six-week peak-readiness gate before this ramp and treat a failed gate as a stop, not a delay.
17. Migrate back-office, storefront and mobile clients off the monolith database (after 16) new
Moves the clients and the 300 back-office users onto the service APIs. Until this happens, the monolith's database remains a dependency even where the logic has already moved.
- Refactor back-office screens to consume service APIs through the gateway, replacing direct SQL access table by table, starting with orders and customers.
- Add aggregation endpoints where a screen needs several services, plus a short-lived cache so 300 staff do not multiply load on the new services.
- Update the server-rendered storefront to call service APIs while keeping the existing rendering path working behind a flag, so a rendering regression is a flag flip rather than a rollback.
- Point the mobile app at the gateway for migrated endpoints while keeping the old endpoints alive for un-updated app versions, since users do not upgrade on your schedule.
- Publish API versioning rules and deprecation windows so teams can change their services without coordinating with client releases.
- Load-test back-office behaviour with 300 concurrent staff on top of peak storefront traffic, since the two now share services.
18. Decommission the monolith core and harden for the second peak (after 17) new
Removes what is left of the monolith and proves the new architecture survives a peak. This step is as much about proving the state is coherent as about deleting code.
- Delete dead code and dropped tables module by module, only after a module has run a full peak or four clean weeks, whichever is longer.
- Keep read-only access to the old database for a defined period for historical and regulatory queries, then archive and decommission it.
- Replace the monolith's remaining cross-module reads with service calls or event-fed projections. The monolith should now be a small set of modules, or nothing at all.
- Re-run the full 12x load test against the new topology across all 8 countries, 3 currencies and 4 languages, and tune autoscaling, connection pools and broker partitions from the results.
- Run chaos game days: kill each service in turn and confirm the storefront degrades gracefully rather than failing completely.
- Confirm the peak-readiness gate before the second peak and publish its evidence. A failed gate defers remaining work rather than risking the peak.
- Write the exit report: final service boundaries, data ownership, runbooks, SLO history, the scope-ladder rung actually reached, and the list of work explicitly deferred to a follow-up program.
- Independent deployability: 100% of releases to extracted services require no coordination with another team and no monolith release, demonstrated for at least 6 services by month 9.
- Independent deployability precedes extraction: at least 4 of the 5 teams release their own artefacts without being separate services by month 5.
- The 30-minute maintenance window is retired by month 6; no release after that date requires a planned outage.
- Deployment lead time from merge to production for a single service is 30 minutes or less, and each team releases at least 3 times per week by month 6.
- Zero unplanned downtime attributable to the migration across the 12 months; platform availability of 99.95% or better inside each peak window.
- Both January and July peaks pass with no migration-caused incident: 12x baseline load sustained, checkout p99 under 5 seconds, error rate under 0.5%, no queue backlog beyond 5 minutes.
- 100% of migration increments that reach production have a rollback demonstrated in a game day and executable in under 30 minutes.
- Hourly data reconciliation shows under 0.001% discrepancy on row counts and checksums per module, with zero unexplained business-invariant violations.
- Cross-module database joins and cross-module writes originating in application code are zero for every module at the moment it is extracted, enforced by database roles and CI checks rather than by review.
- Pricing parity: 100% agreement with the golden master on a corpus of at least 1,000,000 historical requests across all 8 countries, 3 currencies and 4 languages, both before and after cutover.
- Stored procedures touching more than one module's tables: zero for every extracted module.
- Search freshness improves from a nightly rebuild to under 30 seconds between a product change and its visibility in search results.
- Warehouse inventory freshness improves from 15 minutes to under 2 minutes end to end.
- 100% of public APIs of extracted services have golden-master or consumer-driven contract coverage; line coverage is tracked only for newly written service code, where it reaches 80%.
- The peak-readiness gate is passed with published evidence six weeks before both peaks, covering 100% of its defined checks.
- Scope ladder rungs 1–6 are complete within 12 months, or the program stops at a rung boundary in a documented, coherent, peak-safe state.
[SYSTEM]
You are an expert assistant in complex project planning.
Your task is to generate a detailed and structured action plan to reach the main objective in the most professional and most detailed way, no matter how much work or steps will be needed to perform.
Use your internal reasoning processes to think deeply about the problem and create the most comprehensive plan possible.
Take as much time and space as you need to think through all aspects of the problem.
After your thorough analysis, answer with the plan in the requested structure.
Every text field you write will be read by a busy person, so write for them: short sentences, one idea each, in short paragraphs. Text fields accept Markdown: separate paragraphs with a blank line, use a bullet list when you enumerate things and plain paragraphs when you explain or argue, and bold at most one key phrase per paragraph. A text of more than three sentences must be split into paragraphs; never deliver a single unbroken block of text.
[HUMAN]
Main Objective: "A mid-size European fashion retailer runs its e-commerce on a 10-year-old monolith: Java 8 / Spring, about 2 million lines, one PostgreSQL database of 1.2 TB with 350 tables and heavy use of stored procedures and cross-module joins. It serves 8 countries, 3 currencies and 4 languages, with about 40,000 orders a day and peaks of 12x during sales. The monolith contains: the storefront (server-rendered, plus a separate mobile app hitting the same endpoints), catalogue and search (a Lucene index rebuilt nightly), pricing and promotions (the most complex module, 200,000 lines, with country-specific rules nobody fully understands), cart and checkout with three payment providers, order management, inventory synchronised every 15 minutes with the warehouse system via file exchange, customer accounts and loyalty, returns, and a back-office used by 300 staff. Deployments happen every two weeks as a single artefact with a 30-minute maintenance window; test coverage is 25% and mostly unit tests. Five teams of 8 developers, each organised around a business area but all committing to the same repository.
Plan the migration to independently deployable services over 12 months with no feature freeze, no unplanned downtime and the ability to roll back every step, preserving the peak-season capacity (sales in January and July must not be put at risk)."
For your consideration and refinement, here are proposals from the previous round:
Previous Proposal 1 (ID: 1a154427-5ec4-44d9-aff2-f7dd482a0601, Agent: claudeHaiku4.5_initial_1, LLM: anthropic/claude-haiku-4-5):
Estimated Complexity: high
Success Metrics: - All 8 services independently deployed and running in production with zero unplanned downtime during 12-month migration
- Zero data inconsistencies between service-specific databases (validated by monthly reconciliation)
- January and July peak seasons proceed with no degradation: 480k orders/day processed within 5-second checkout SLA
- Test coverage increased from 25% to 70%+ for all extracted services
- Every service deployment is fully automated; manual rollback procedures tested and <30 minutes to execute
- Order processing latency (cart → confirmation) unchanged or improved: maintained under 5 seconds at peak load
- All 5 teams deploying independently: no cross-team deployment coordination required after cutover
- Pricing/promotions service successfully extracted with all 200k LOC of country-specific rules preserved and validated
- Search latency improved or maintained despite architectural change
- Inventory synchronization with warehouse continues reliably: no missed 15-minute sync cycles
- Back-office operations for 300 staff members unaffected by migration; service aggregation endpoints maintain <500ms latency
- Zero payment processing regressions: all three payment providers functioning, fraud detection active, PCI-DSS compliance maintained
Steps (24):
1. Current State Documentation & Target Architecture
Create a detailed map of the monolith to inform service extraction strategy.
- Audit all modules: storefront, catalogue, search, pricing/promotions, cart, checkout, orders, inventory, customers, loyalty, returns, back-office
- Map dependencies between modules, identifying cross-module calls and data flows
- Model future bounded contexts using Domain-Driven Design
- Create technology inventory (libraries, frameworks, protocols)
- Document interface contracts for each module
- Identify which teams own which modules for organizational alignment
2. Data Dependency Analysis & Dual-Write Strategy (depends on: 1)
Untangle the 1.2TB database to support service independence without blocking progress.
- Map all 350 tables to future service domains
- Identify cross-service joins and stored procedures that span domains
- Design per-service database schemas with minimal denormalization
- Create data versioning framework to support rollback
- Plan dual-write patterns: how old monolith and new services will sync during transition
- Document eventual-consistency requirements and conflict resolution
- Design data migration runbooks with clear rollback steps
3. Test Coverage Audit & Improvement Roadmap (depends on: 1)
Build confidence for service extraction by eliminating test blindness.
- Audit current 25% test coverage by module
- Identify coverage gaps in modules scheduled for early extraction
- Establish target of 70%+ coverage for modules being extracted
- Prioritize integration tests over unit tests given monolith complexity
- Create quality gates: no service extraction below 60% module coverage
- Plan for continuous improvement during extraction phases
4. Peak-Season Window Planning & Risk Framework (depends on: 1)
Protect January and July sales by scheduling extractions during safe windows.
- Map annual peak periods: January sales (peak orders), July sales, plus any promotional events
- Define 4-week freeze windows before/during peaks
- Identify lowest-risk windows in each month for major changes
- Create rollback procedures that execute in <30 minutes
- Establish monitoring escalation for changes made near peak season
- Document communication plan with business teams
5. Observability Foundation Setup
Instrument the system for real-time visibility during migration.
- Deploy centralized logging (ELK, Splunk, or similar)
- Set up metrics collection (Prometheus, Datadog, or similar)
- Implement distributed tracing (Jaeger, Zipkin) for request flows across services
- Create dashboards for: requests/sec, error rates, latency percentiles, database load
- Define SLOs: order processing latency p99, checkout success rate, payment authorization speed
- Set up alerts for SLO violations and anomalies
6. Feature Flags, Containerization & API Gateway
Build the technical foundation for canary deployments and controlled traffic routing.
- Implement feature flag system (LaunchDarkly, custom Spring Boot solution, etc.)
- Containerize monolith and all new services (Docker)
- Set up container orchestration (Kubernetes or similar) with service templates
- Deploy API gateway (Kong, AWS ALB) with routing rules
- Implement service-to-service authentication (mTLS, JWT)
- Configure rate limiting and circuit breakers at gateway
7. Deployment Pipeline & Automated Rollback (depends on: 6)
Enable safe, automated deployments with reliable rollback capability.
- Implement CI/CD pipeline with automated testing gates
- Set up blue-green deployment: run old and new versions in parallel, switch traffic atomically
- Build canary deployment capability: route 5%→10%→50%→100% of traffic gradually
- Automate rollback: trigger on error rate threshold, latency spike, or manual command
- Create deployment runbooks for each service
- All deployments must be independent; monolith keeps 2-week cycle until fully extracted
8. Test Coverage Improvement to 70%+ (depends on: 3)
Close test gaps before extracting services to reduce rollback risk.
- Implement integration tests for key flows: order creation, payment processing, inventory updates
- Add contract tests between modules to catch breaking changes
- Use mutation testing to verify test quality
- Target 70%+ coverage for: pricing module, payment module, order management
- Establish automated quality gates: coverage <70% blocks extraction of that service
- Include tests for peak-load scenarios (40k→480k orders)
9. Search/Catalogue Service Extraction & Validation (depends on: 7, 8, 3)
Extract the first service: search is read-heavy, isolated, and low-risk.
- Extract catalogue and search indexing logic from monolith
- Build as independent Spring Boot service with own codebase/deployment
- Create new database schema for catalogue (subset of 350 tables)
- Implement dual-write: monolith writes to both old Lucene index and new service
- Implement canary routing: API gateway sends 10% of search requests to new service, monitor latency and correctness
- Validate results match between old and new service (checksums on result sets)
- Gradually increase traffic: 10%→25%→50%→100%
- Keep dual-write active for 2 weeks post-cutover for rollback safety
10. Event Bus & Service Mesh Infrastructure (depends on: 9)
Build async communication layer required for multi-service coordination.
- Deploy message broker (Kafka recommended for ordering guarantees and peak load of 40k/sec)
- Define domain events: OrderPlaced, PaymentAuthorized, InventoryReserved, etc.
- Implement event schema versioning and compatibility
- Set up service discovery (Consul, Kubernetes DNS)
- Implement distributed configuration management
- Create event publishing library for services to use
- Document saga patterns for multi-step workflows
- Test message broker under peak load (480k messages/day)
11. Inventory Service Extraction & Warehouse Sync (depends on: 10)
Extract inventory as second service: well-bounded, drives warehouse sync complexity.
- Extract inventory logic and reservation system
- Build inventory service with own database schema
- Implement dual-write from monolith to both old and new inventory data
- Preserve existing 15-minute warehouse file exchange, but now via service
- Create inventory events: ReservationCreated, ReleaseRequested
- Implement canary rollout: gradual traffic shift like search service
- Test warehouse sync under peak load
- Validate inventory consistency across monolith and new service before full cutover
12. Customer/Loyalty Service Extraction & Auth Refactoring (depends on: 10)
Extract customer accounts and loyalty: enables independent scaling of auth layer.
- Extract customer account and loyalty program logic
- Build customer service with own database schema
- Separate authentication from monolith: implement API for token validation
- Support multi-tenant loyalty rules (8 countries, country-specific points rules)
- Implement canary rollout with real customer sessions
- Create backwards-compatible customer APIs
- Test account operations at peak concurrency (concurrent logins, loyalty point updates)
- Plan for session management: ensure distributed sessions work across services
13. Saga Pattern Library & Order Orchestration Framework (depends on: 10)
Build the framework for managing distributed transactions across services.
- Implement saga pattern library: choreography-based (event-driven) and orchestration-based patterns
- Support compensating transactions: if payment fails, return inventory reservation
- Handle timeouts and retries with exponential backoff
- Implement idempotency keys to prevent duplicate charges on retries
- Test saga execution under peak load and network failures
- Document patterns for: order placement saga, payment saga, return saga
- Create distributed tracing for saga flows
14. Pricing/Promotions Service Extraction (Phase 1: Extract As-Is) (depends on: 13)
Begin extraction of most complex module (200k LOC) without initial refactoring.
- Extract pricing engine as-is with minimal refactoring to reduce initial risk
- Preserve all country-specific rules and business logic
- Build service boundary: accept pricing requests, return prices/promotions
- Create feature tests that document all 200k LOC behavior
- Map all promotion types to test scenarios
- Test with real country/currency/language combinations
- Implement as service behind same interface initially
- Prepare for Phase 2 refactoring once stable in production
15. Pricing/Promotions Service Refinement (Phase 2: Rules Refactoring) (depends on: 14)
Gradually improve pricing service maintainability without breaking production.
- Document the 200k LOC of complex rules in machine-readable format
- Refactor rules engine into composable components
- Build DSL for country-specific promotion rules
- Decompose monolithic rule evaluation into smaller decision trees
- Use feature flags to A/B test refactored rules vs old implementation
- Optimize performance: reduce calculation time for promotions at checkout
- Validate that refactored logic matches original behavior across all countries
16. Payment Service Extraction & Security Hardening (depends on: 13)
Extract payment processing with extreme rigor given PCI/regulatory requirements.
- Separate payment logic from checkout: payment validation, three-provider integration
- Build payment service with encrypted credential storage, no raw card data in logs
- Implement fraud detection integration and decline handling
- Audit for PCI-DSS compliance: minimal data exposure, encrypted transport
- Implement E2E testing for all three payment provider scenarios
- Load test payment service: 500+ payments/sec at peak
- Implement idempotent payment requests: prevent double-charging on failures
- Create detailed rollback procedures: how to fall back to direct monolith payment handling
17. Order Service Extraction & Event Stream (depends on: 13, 16)
Extract order management: central service coordinating multiple workflows.
- Extract order creation, status tracking, and management logic
- Build order service with event stream: OrderCreated, PaymentAuthorized, InventoryReserved, OrderConfirmed
- Support order querying by all 5 teams (inventory, fulfillment, customer service, etc.)
- Implement order event sourcing for audit trail and replay capability
- Create order state machine: validate state transitions
- Test concurrent order processing at peak load (40k orders/day)
18. Checkout Service Composition via Saga (depends on: 17)
Compose checkout from independent payment, inventory, and order services using sagas.
- Build checkout service that orchestrates: cart validation → pricing calculation → inventory reservation → payment authorization → order creation
- Use saga pattern: if payment fails, release inventory reservation automatically
- Implement distributed transaction semantics: all-or-nothing guarantee
- Support three payment providers transparently
- Test all failure scenarios: payment declines, inventory unavailable, warehouse system down
- Implement timeout handling: what happens if inventory service is slow at peak
- Validate checkout latency remains <5 seconds at peak load
19. Back-Office Integration with Service APIs (depends on: 18)
Update back-office (used by 300 staff) to coordinate across all services.
- Create service aggregation endpoints: orders endpoint calls order service + payment service + inventory service
- Update back-office UI to call new service APIs instead of monolith
- Implement service discovery: handle service availability transparently
- Create caching layer: reduce latency for frequently accessed data
- Test with 300 concurrent staff users
- Implement search across all orders/customers via service APIs
- Add retry logic and timeouts to handle service failures gracefully
20. Storefront & Mobile App Refactoring (depends on: 19)
Update client applications to use new service architecture transparently.
- Update server-rendered storefront templates to call service APIs
- Update mobile app endpoints (already separate, now points to services via gateway)
- Implement client-side caching: reduce latency impact of distributed calls
- Maintain backwards compatibility: old clients must still work
- Update API versioning: enable service changes without breaking clients
- Implement request tracing: correlate user requests across services
- Test storefront and mobile under peak load scenario (480k orders/day)
21. Legacy Database Deprecation & Data Migration (depends on: 20)
Safely decommission the monolith database once all services are independent.
- Verify all data has been migrated to service-specific databases
- Maintain 2-week read-only access to old database for emergency queries
- Archive old database snapshots (regulatory requirement for order history)
- Update backup/recovery procedures: now per-service instead of monolith
- Verify no remaining cross-service joins depend on monolith schema
- Document data mapping for future reference
- Decommission old database infrastructure
22. Load Testing & Performance Optimization (depends on: 21)
Validate new architecture meets production capacity requirements.
- Simulate peak load scenario: 480k orders/day (40k baseline × 12)
- Test across 8 countries, 3 currencies, 4 languages simultaneously
- Identify bottlenecks: service latency, database query performance, message broker throughput
- Optimize hot paths: pricing calculations, search queries, payment processing
- Test cache effectiveness: Lucene search response times, pricing cache hit rates
- Validate database connection pools don't exhaust under peak load
- Create load testing environment: realistic data, all 5 teams' concurrent usage
23. Documentation & Knowledge Transfer (depends on: 22)
Codify migration experience and new architecture for long-term success.
- Document final service boundaries: APIs, responsibilities, data ownership
- Create operational runbooks: how to deploy each service, how to handle common failures
- Record architecture decision log: why services were split this way
- Document data consistency model: eventual consistency patterns used
- Create troubleshooting guides: common issues and resolutions
- Train each team on their service and API contracts with other services
- Record key decisions and trade-offs (e.g., why search is separate from catalogue, why pricing is monolithic within its service)
24. Production Stabilization & 30-Day Monitoring (depends on: 23)
Establish stable operation and prove architecture meets requirements.
- Run 30-day monitoring period observing: error rates, latency, resource utilization
- Establish performance baselines: P99 latency per service, throughput, error rates
- Document SLO achievements: order processing speed, payment success rate, search latency
- Create incident playbooks based on observed issues
- Validate peak-load handling (Jan/July sales go normally through new architecture)
- Establish team on-call procedures for service alerts
- Plan for service scaling: autoscaling policies, capacity planning
- Complete full rollback verification: ensure rollback to monolith is always possible
Previous Proposal 2 (ID: f92888a9-2fa0-4ee5-a4ab-426fc426ffab, Agent: deepseek-flash_initial_2 - YOUR OWN previous proposal, LLM: deepseek/deepseek-flash):
Estimated Complexity: high
Success Metrics: - 100% of planned service extractions completed within 12 months.
- Zero unplanned downtime during January and July peak sales.
- All new services independently deployable with <5 minute lead time.
- 100% of deployments rollback-able within 5 minutes.
- 80% of traffic served by new services by end of 12 months.
- Test coverage increased to 60% for critical modules.
- Deployment frequency increased from bi-weekly to daily.
- Mean time to recovery (MTTR) < 30 minutes.
- Change failure rate < 15%.
- All stored procedures refactored or migrated to services.
- Database decomposed into 5+ independent databases.
- Peak load capacity sustained at 12x with <1% error rate.
Steps (15):
1. Mobilize Program and Define Target Architecture
Launch the migration program and define the target architecture. This step sets the foundation for all subsequent work.
Key activities:
- Establish a steering committee with business, architecture, and operations representatives.
- Conduct domain-driven design workshops to identify bounded contexts and service candidates.
- Define the target architecture: API gateway, service mesh, event-driven integration, and data ownership per service.
- Prioritize service extraction based on business value, risk, and coupling.
- Create architecture decision records (ADRs) and a service roadmap.
Output: a shared vision and prioritized backlog for the migration.
2. Build Platform Foundation for Independent Deployments (depends on: 1)
Build the platform foundation required for independent deployments. This includes infrastructure, tooling, and golden paths.
Key activities:
- Provision a Kubernetes cluster with namespaces for each service.
- Set up CI/CD pipelines per service using GitLab CI or ArgoCD.
- Deploy an API gateway (e.g., Kong) and service mesh (e.g., Istio) for traffic management.
- Implement observability: centralized logging (ELK), metrics (Prometheus/Grafana), and tracing (Jaeger).
- Set up secrets management (Vault) and configuration management.
- Create golden path templates for new services to reduce boilerplate.
Output: a production-ready platform where teams can deploy services independently.
3. Implement Strangler Fig Facade and Monolith Instrumentation (depends on: 2)
Implement the strangler fig facade and instrument the monolith. This allows incremental migration without disrupting users.
Key activities:
- Deploy the API gateway to route requests to the monolith or new services based on path or header.
- Modify the monolith to expose REST APIs for key domains (e.g., catalogue, customer).
- Implement the transactional outbox pattern to publish domain events from the monolith.
- Set up change data capture (CDC) from the monolith PostgreSQL to Kafka using Debezium.
- Introduce feature flags for routing and canary releases.
- Ensure all changes are backward compatible and can be rolled back.
Output: a facade that enables gradual traffic shifting and a data pipeline for synchronization.
4. Establish Continuous Delivery and Test Automation (depends on: 1)
Establish continuous delivery and test automation to support safe, frequent deployments.
Key activities:
- Increase automated test coverage for critical monolith modules (target 60%).
- Implement consumer-driven contract testing (Pact) between monolith and new services.
- Set up automated regression test suites for end-to-end flows.
- Integrate tests into CI/CD pipelines with quality gates.
- Enable blue-green and canary deployments for both monolith and services.
Output: a reliable deployment pipeline that supports rollback and rapid feedback.
5. Extract Catalogue and Search Service (depends on: 3, 4)
Extract the Catalogue and Search service. This is a read-heavy, low-coupling module, making it a good first candidate.
Key activities:
- Create a new Catalogue service with its own datastore (PostgreSQL for product data, Elasticsearch for search).
- Implement data synchronization from the monolith via CDC and events.
- Migrate read APIs for product listing and search to the new service via the gateway.
- Use feature flags to gradually shift traffic, with fallback to the monolith.
- Monitor performance and rollback if issues arise.
Output: an independently deployable Catalogue service serving a portion of traffic.
6. Extract Customer Accounts and Loyalty Service (depends on: 3, 4, 5)
Extract the Customer Accounts and Loyalty service. This service manages profiles, addresses, and loyalty points.
Key activities:
- Create a new Customer service with its own database.
- Synchronize data from the monolith via events (customer created, updated).
- Migrate profile management and loyalty APIs to the new service.
- Keep authentication in the monolith initially to reduce risk.
- Redirect customer API calls to the new service gradually.
Output: an independently deployable Customer service with data ownership.
7. Extract Inventory Service (depends on: 3, 4)
Extract the Inventory service. This service consumes the warehouse file feed directly and maintains real-time inventory.
Key activities:
- Create an Inventory service that reads the warehouse file feed (SFTP) and parses it.
- Publish inventory update events to Kafka.
- Migrate inventory queries from the monolith to the new service.
- Ensure the monolith and other services consume inventory events instead of querying the monolith DB.
Output: an independently deployable Inventory service with real-time updates.
8. Extract Returns Service (depends on: 3, 4, 6)
Extract the Returns service. This module is relatively independent and can be extracted early.
Key activities:
- Create a Returns service with its own database.
- Consume order and customer events to validate returns.
- Migrate returns UI and APIs to the new service.
- Ensure integration with order management for refunds.
Output: an independently deployable Returns service.
9. Peak Season Readiness and Resilience Engineering (depends on: 1)
Prepare for peak seasons and implement resilience engineering. This is critical to avoid downtime during January and July sales.
Key activities:
- Conduct load testing for 12x peak on new services and the monolith.
- Implement circuit breakers, bulkheads, rate limiting, and auto-scaling.
- Define change freeze periods: one month before and during January and July sales.
- Plan migration activities outside freeze windows.
- Run game days for failure scenarios and rollback drills.
Output: a system that can withstand peak loads and a schedule that protects peak seasons.
10. Extract Cart Service (depends on: 3, 4, 7)
Extract the Cart service. The cart is a stateful component that requires careful handling.
Key activities:
- Create a Cart service with its own datastore (e.g., Redis or PostgreSQL) for session and cart items.
- Use the API gateway to route cart operations.
- Synchronize with the monolith via events for product and inventory validation.
- Ensure idempotency and session stickiness.
- Gradually migrate cart traffic using feature flags.
Output: an independently deployable Cart service.
11. Extract Order Management and Checkout Orchestration (depends on: 10, 6, 7, 9)
Extract Order Management and Checkout Orchestration. This is the core transactional flow and requires a saga pattern.
Key activities:
- Create an Order service that orchestrates checkout using the saga pattern.
- Integrate with payment providers, inventory, pricing, and customer services.
- Migrate order placement and management APIs.
- Use events for order status updates.
- Ensure distributed transaction consistency and compensation logic.
Output: an independently deployable Order service handling the checkout flow.
12. Extract Pricing and Promotions Service (depends on: 11)
Extract the Pricing and Promotions service. This is the most complex module with 200k lines of rules.
Key activities:
- Analyze and document the existing pricing rules and country-specific logic.
- Implement a new Pricing service, possibly using a rules engine (e.g., Drools).
- Migrate pricing calculations and promotions to the new service.
- Execute after other services are stable and outside peak seasons.
- Use extensive testing and canary releases.
Output: an independently deployable Pricing service with clear rules.
13. Database Decomposition and Stored Procedure Refactoring (depends on: 3)
Decompose the database and refactor stored procedures. This is a cross-cutting concern that runs alongside service extraction.
Key activities:
- Start with logical separation: create schemas per service and move tables gradually.
- Refactor stored procedures into application code or move them to services.
- Eventually, give each service its own database instance.
- Use CDC and dual-write for data consistency during transition.
- Keep the monolith DB as source of truth until cutover.
Output: a decomposed database with clear data ownership.
14. Reorganize Teams for Independent Deployment (depends on: 1, 2)
Reorganize teams for independent deployment. This step enables long-term autonomy.
Key activities:
- Reorganize teams around services (stream-aligned teams).
- Give each team ownership of its service's repository, CI/CD, and on-call.
- Implement an internal developer platform for self-service deployments.
- Establish service level objectives (SLOs) and error budgets.
Output: autonomous teams that can deploy independently.
15. Post-Migration Optimization and Monolith Decommissioning (depends on: 12)
Optimize after migration and decommission the monolith. This step wraps up the migration.
Key activities:
- After each service extraction, remove dead code from the monolith.
- Gradually reduce the monolith to a smaller core (e.g., back-office).
- Plan eventual decommissioning of monolith components.
- Document learnings and update architecture.
Output: a leaner monolith and a fully service-oriented architecture.
Previous Proposal 3 (ID: 14efa153-1aa1-47b0-9435-75fba2e57cfe, Agent: qwen3.8-flash_initial_3, LLM: alibaba/qwen3.8-flash):
Estimated Complexity: high
Success Metrics: - **Zero Downtime**: Achieve 100% availability of the e-commerce platform throughout the 12 months, including planned maintenance windows.
- **Deployment Independence**: New services can be deployed independently; no code commit forces a full 30-minute monolith downtime. Time-to-deploy for a new service < 5 minutes.
- **Database Decoupling**: Eliminate cross-service SQL joins. The monolith database write load decreases by 90%.
- **Peak Capacity**: System handles 12x traffic load (approx. 480k orders/day) with < 200ms latency at P95 during load tests.
- **Search Latency**: Product availability reflected in search results within < 30 seconds of inventory update (replacing nightly rebuild).
- **Pricing Stability**: 0% deviation in price calculation results between the new architecture and the legacy 'golden master' characterization tests.
Steps (10):
1. Foundation: Infrastructure, Observability, and Safety Net
Before extracting any service, the team must build the 'operating system' for distributed applications. This step focuses on enabling independent deployment and providing real-time visibility into the legacy monolith. The goal is to create a safety net that makes subsequent refactoring steps low-risk and reversible.
* **CI/CD Pipeline**: Implement a dual-track pipeline. The existing monolith gets a 'speedy' pipeline for hotfixes, while a new pipeline infrastructure is set up (e.g., Kubernetes/ECS) ready for independent service deployment.
* **Observability Suite**: Deploy centralized logging (ELK/Loki), metrics (Prometheus/Grafana), and crucially, **Distributed Tracing** (Jaeger/Zipkin). Even within the monolith, we must map request flows to identify coupling.
* **Service Mesh / API Gateway**: Install an API Gateway (e.g., Kong, Nginx ingress) in front of the monolith. This is the 'strangler fig' entry point. All traffic must flow through here. We will use it to route traffic to new services or fallback to the monolith.
* **Feature Flags**: Integrate a feature management system (e.g., LaunchDarkly, Unleash) to decouple deployment from release. This allows us to deploy code that is inactive and test it behind flags.
2. Domain Analysis and Boundary Definition (Strangler Pattern) (depends on: 1)
You cannot extract a service without knowing the domain. With 2M lines and 'unknown' pricing logic, this step is about mapping the terrain. We aim to identify low-risk, high-cohesion boundaries for the first extractions and mark the 'danger zones' (Pricing) for later.
* **Event Storming**: Run workshops with the five teams to map business flows (e.g., 'Checkout', 'Return') and identify command/event boundaries.
* **Code Hotspot Analysis**: Use static analysis tools (e.g., SonarQube, CodeScene) to find files changed together (logical coupling) and complex methods.
* **Dependency Matrix**: Create a matrix showing which database tables are accessed by which application modules. This is critical for the database refactoring later.
* **Service Extraction Plan**: Finalize the order of extraction. Recommended: **Search/Catalogue** (read-heavy, low transactional consistency risk) or **Inventory** (async, distinct boundary). Avoid 'Pricing' initially due to complexity and 'Checkout' until foundational identity is stable.
3. Data Platform Strategy: Outbox Pattern and CDC (depends on: 2)
The 1.2TB PostgreSQL DB with stored procedures is the 'database of doom' for migration. We must stop using cross-module SQL joins. This step introduces a data change capture layer to allow services to communicate via events rather than DB writes.
* **Database Isolation**: Begin identifying tables exclusive to the chosen first domain (e.g., Catalogue tables). Grant strict read-only access to other modules if possible, or refactor code to remove cross-table joins.
* **Change Data Capture (CDC)**: Deploy a tool (e.g., Debezium or Kafka Connect) to stream PostgreSQL WAL logs to a message broker (Kafka/Pulsar). This creates a stream of data changes that can be consumed by other services.
* **Transaction Outbox**: Refactor the monolith code to use an 'Outbox Pattern' for domain events. Instead of just writing to the DB, it also writes a message to an 'Outbox' table in the same transaction. A relay process moves this to Kafka. This ensures 'at least once' delivery and keeps the monolith's transactional integrity while enabling async communication.
4. Extraction of First Service (The 'Read-Only' Pilot) (depends on: 1, 3)
To learn safely, we extract a 'read-only' service with no transactional complexity. The **Product Catalogue/Search** is the best candidate. It is currently Lucene-based, rebuilt nightly. We will move to real-time indexing to improve product freshness.
* **Build the Catalogue Service**: Create a new microservice that owns the Catalogue database tables. It exposes gRPC/REST endpoints for fetching products.
* **Real-time Sync**: The new service subscribes to the CDC events for product changes (from S3). It updates its internal Lucene/Opensearch index in real-time. This eliminates the nightly rebuild and provides immediate search visibility.
* **Dual Read Path**: The monolith code for 'Search' is modified to check a feature flag. If enabled, it calls the new Catalogue Service; otherwise, it uses the old internal Lucene logic.
* **Shadow Traffic**: Use the API Gateway to duplicate live traffic. Send requests to both the monolith and the new service. Compare the responses. Only when error rates are 0% do we flip the feature flag for production traffic.
5. Extraction of Identity and Customer Accounts (depends on: 4)
Next, we extract the **Customer Account** domain. This serves both the storefront and the mobile app. This is a write-heavy domain, requiring careful transaction handling with the legacy monolith during the transition.
* **Service Implementation**: Implement the 'Customer Service' (JWT generation, profile management, authentication). It owns its own database schema (User, Address).
* **Sync with Legacy**: The service publishes 'UserUpdated' and 'UserCreated' events via Outbox/CDC. The monolith listens to these events to keep its local copy of user data synchronized.
* **Strangler Endpoint**: The API Gateway routes '/api/login', '/api/account' traffic directly to the new service. The monolith stops handling these requests. Front-end applications must be updated to handle the new response format (versioning).
* **Database Decoupling**: Over time, remove read access to the monolith's user table for all other domains, forcing them to use the Identity service.
6. Extraction of Inventory Synchronization (depends on: 5)
Inventory is currently updated every 15 minutes via files. This is a bottleneck. We will extract this into a service that integrates directly with the Warehouse Management System (WMS).
* **Inventory Service**: Build a service that consumes warehouse data feeds (replacing the file drop). It updates a centralized stock level view.
* **Event Publishing**: When stock levels change, publish `StockLevelChanged` events to Kafka.
* **Monolith Integration**: Refactor the Cart/Checkout code in the monolith to listen to these events to maintain a local cached view of inventory or to check stock via an API call rather than a SQL join. This removes the 15-minute latency.
* **Consistency Model**: Since inventory is high-concurrency, design a reservation system (Saga) for this service to prepare for the future extraction of Checkout.
7. The 'Black Box' Strategy for Pricing and Promotions (depends on: 6)
The pricing module (200k lines, unknown rules) cannot be rewritten safely from scratch. We treat it as a 'legacy core'. We will wrap it in a service but keep the internal logic untouched in the monolith initially, or isolate it.
* **Characterization Tests**: Write massive integration tests that record the input/output of the pricing module for all 8 countries and 3 currencies. This creates a 'golden master'.
* **Decouple Dependencies**: Refactor the pricing code to rely only on 'Customer', 'Product', and 'Inventory' data fetched via interfaces, not direct DB calls. This prepares it for extraction.
* **Extract as 'Black Box'**: Wrap the existing pricing logic into a new `Pricing Service`. Move the 200k lines of code into this project. It calls a dedicated read-replica database of the pricing tables. This service does not communicate with others directly but is called by the 'Cart' service.
* **Validation**: Run 'shadow mode' traffic against this new service to ensure it matches the golden master before routing any production traffic.
8. Orchestration Layer: Cart and Checkout (The Saga) (depends on: 7)
Checkout is the highest risk. It requires distributed transaction management. We will implement the Cart as a service and the Checkout process as an orchestrator using Sagas.
* **Cart Service**: Extract cart logic into its own stateless/stateful service (Redis-backed). This decouples the browsing experience from the order processing.
* **Checkout Orchestrator**: Build a new 'Order Service' that does not do the work itself but coordinates the process. When a checkout starts, the Order Service begins a **Saga**.
* **Saga Steps**: 1. Validate Pricing (via Pricing Service), 2. Reserve Inventory (via Inventory Service), 3. Authorize Payment (via Payment Service), 4. Create Order Record. If step 3 fails, step 1/2 must be compensated (rollback).
* **Idempotency**: Ensure all services in the saga accept Idempotency Keys to prevent double-charging or double-stock deduction.
9. Extraction of Payments and Order Management (depends on: 8)
Complete the order lifecycle. Move payment integration and order status tracking out of the monolith.
* **Payment Gateway**: Extract the integration with the 3 providers into a `Payment Service`. This service handles webhooks, refunds, and tokenization (PCI scope reduction).
* **Order Management System (OMS)**: Move the database table `orders` and associated history into a new `Order Service`. It consumes the events generated by the Checkout Saga.
* **Back-office Migration**: The back-office (300 staff) is likely server-rendered. Refactor these screens to consume the new `Order Service` APIs. Remove the back-office's direct SQL access to the orders table. This is crucial for reducing load on the monolith DB.
10. Legacy Cleanup and Peak Season Preparation (depends on: 9)
The monolith should now be a 'hollowed-out' shell (mostly just the legacy pricing rules inside a service or a 'legacy' module). We prepare for the peak sales in Jan/July.
* **Database Downsizing**: Detach the schema ownership. The monolith should ideally only connect to a 'read-only' replica for historical data or a small remnant DB.
* **Performance Tuning**: The new architecture is now the single point of failure. Optimize the message broker (Kafka) and API Gateway for 12x traffic.
* **Chaos Engineering**: Run game-days testing resilience. Kill a service (e.g., Search) and ensure the storefront degrades gracefully (shows empty search results but allows cart access).
* **Final Monolith Decommission**: Identify the remaining monolith code. Delete it. If it's just a 'legacy gateway', replace it with pure API routing. The 'Monolith' label should now refer only to the Pricing Service or similar, not a single deployable unit.
Please, considering the previous proposals as ideas that could be considered, focus on the main objective and generate an IMPROVED proposal or a completely DIFFERENT perspective if you deem it appropriate. Only if you consider any of them is amazing and impossible to improve, answer with the same proposal.
The plan has these parts:
- "steps": the list of steps, each with "step_id" (a short label unique within this proposal, such as S1, S2, S3), "title" (a short, descriptive title), "description" (what the step does and how, in Markdown: a short opening paragraph and then, if there are several concrete things to say, a bullet list) and "dependencies" (the step_ids of the other steps of THIS proposal that must be completed first; empty if none).
- "estimated_complexity": "low", "medium" or "high".
- "success_metrics": clear and measurable success metrics, one per line as a bullet list.
Think deeply about the problem, considering all aspects and implications. Develop a comprehensive understanding of what needs to be done to achieve the objective, then produce the plan.
Answer with a single JSON object, and nothing else, that conforms to this JSON schema:
{"description": "The structure every proposing agent must answer with.", "properties": {"steps": {"items": {"description": "One step of a proposed plan. Dependencies are step_ids of the same proposal.", "properties": {"step_id": {"title": "Step Id", "type": "string"}, "title": {"title": "Title", "type": "string"}, "description": {"title": "Description", "type": "string"}, "dependencies": {"items": {"type": "string"}, "title": "Dependencies", "type": "array"}}, "required": ["step_id", "title", "description", "dependencies"], "title": "Step", "type": "object", "additionalProperties": false}, "title": "Steps", "type": "array"}, "estimated_complexity": {"title": "Estimated Complexity", "type": "string"}, "success_metrics": {"title": "Success Metrics", "type": "string"}}, "required": ["steps", "estimated_complexity", "success_metrics"], "title": "ProposalContent", "type": "object", "additionalProperties": false}
{"steps": [{"step_id": "S1", "title": "Program setup, peak-aware calendar, rollback charter and scope ladder", "description": "Turns the brief's constraints into an operating rhythm that everything later obeys. The binding constraint in this objective is the calendar, not the technology, so the calendar is decided first.\n\n- Run a two-week inception to baseline the current state: build time, deployment lead time, change failure rate, MTTR, MTTR, per-module change frequency, database load profile. Progress must be measurable, not asserted.\n- Declare hard freezes from 1 December to 15 January and 1 June to 15 July. During a freeze only rollback-enabling and hardening changes are allowed.\n- Confirm the two open delivery windows of the year (roughly February–May and August–November) and accept in writing that only these windows carry migration increments.\n- Set the soak rule: no change on the checkout path lands within four weeks of a freeze; anything that would violate it is deferred to the next window.\n- Define the peak-readiness gate that runs six weeks before each peak: 12x load test, capacity headroom check, rollback rehearsal, error-budget review. The gate is pass/fail and its evidence is published.\n- Write the rollback charter: every increment ships an expand/contract database change, a feature-flag kill switch, and a rehearsal recorded in a game day. No go-live without a rehearsed rollback.\n- Publish the scope ladder: a ranked list where rungs 1–6 deliver the core objective and rungs 7+ are optional. Slippage means stopping at a rung boundary, never mid-increment.\n- Set the capacity budget at 40–50% of the five teams' capacity for migration alongside normal feature work, and staff the ladder to fit that budget rather than to fill the year.\n- Create a migration enablement squad of six engineers drawn on rotation from the five teams. It owns the platform, the shared cuts and the risky shared data work.", "dependencies": []}, {"step_id": "S2", "title": "Executable architecture map, table ownership and boundary enforcement", "description": "Produces an architecture map that the build itself enforces. Five teams committing to one repository will silently re-couple anything that is separated and not policed, so enforcement is part of the map, not a later step.\n\n- Instrument the monolith with distributed tracing and let it run four weeks. Real call paths beat static imports for finding true coupling.\n- Build a table-to-module and query-to-module map by parsing every SQL statement, ORM mapping and stored procedure in the codebase, cross-checked against the database's own query logs.\n- Score each candidate service on four axes: coupling, transactional risk, change frequency and peak-path criticality. This ranking, not intuition, drives the extraction order.\n- Assign every one of the 350 tables to exactly one owning module. Tables nobody can own are declared contested and scheduled into the data work of S7.\n- Add ArchUnit rules to CI that fail the build on any new cross-module Java dependency, with existing violations frozen into a baseline file that may only shrink.\n- Add a SQL linter to CI that fails on cross-module joins and cross-module writes, with the same shrinking baseline.\n- Publish the target service list, the owning team per service, and the reasoning as architecture decision records.\n- Hold a mid-program review at month six to re-rank the scope ladder using what the map actually showed. This is the one planned re-planning point of the program.", "dependencies": ["S1"]}, {"step_id": "S3", "title": "Delivery platform: per-module pipelines, gateway, feature flags, environments", "description": "Builds the delivery and traffic machinery that makes every later step reversible. No module is extracted until its team can deploy, flag and route on its own.\n\n- Extend the platform foundation on Kubernetes (or the existing container platform if one exists) with one namespace per service, quotas and autoscaling policies sized for a 12x peak.\n- Put an API gateway in front of the monolith as the strangler entry point. Storefront, mobile and back-office traffic all flow through it from day one, even while it routes everything to the monolith.\n- Give every module its own CI/CD pipeline and its own environment. The monolith keeps its current pipeline for hotfixes until S5 replaces it.\n- Deploy a feature-flag service and require every new call path to be flag-guarded. Flags are the primary rollback instrument for the whole program.\n- Introduce secrets management and per-environment configuration so changing behaviour never requires a monolith redeploy.\n- Define golden-path templates for a new service: build, pipeline, observability, health checks, flag integration, database migration tool. Extraction must not start from a blank page.\n- Reserve two permanent environments: a full-size production-like soak environment and a load-test environment capable of generating 12x traffic against production-shaped data.", "dependencies": ["S1", "S2"]}, {"step_id": "S4", "title": "Observability, business SLOs, error budgets and the automated rollback controller", "description": "Makes the system observable enough that a canary is judged automatically and reverted without a human guessing. This is the prerequisite for the rollback promise made in every later step.\n\n- Deploy centralized logging, metrics and distributed tracing, with trace correlation working across the gateway, the monolith and every new service from the start.\n- Instrument the monolith's blind spots: query latency by module, connection-pool saturation, Lucene rebuild duration, warehouse file-exchange lag.\n- Define SLOs on business outcomes, not infrastructure: checkout success rate, order confirmation p99, search latency, payment authorisation rate, price computation latency, warehouse sync freshness.\n- Attach an error budget to each SLO and write the policy: when a service burns budget, its rollout stops automatically and its flags revert. No negotiation during a peak.\n- Build the rollback controller: on error-rate or latency divergence beyond threshold during a canary, the gateway shifts traffic back and flags are disabled without human action.\n- Create per-service dashboards a tired engineer can read at 03:00, plus one program dashboard showing progress against the scope ladder.", "dependencies": ["S3"]}, {"step_id": "S5", "title": "Split the deployment unit and retire the 30-minute maintenance window", "description": "Delivers the objective's headline — independently deployable units — before any process separation, by splitting the build and the release train while the code still runs together. This is the cheapest large win available and it removes the maintenance window.\n\n- Split the single artefact into one build per owning module with a shared parent, so a module can be built, tested and released on its own.\n- Allow modules to be released as separate artefacts on the existing runtime first. Independent deployability is a build and release property long before it is a topology property.\n- Retire the two-week coordinated release train. Each team gets its own pipeline, cadence and on-call rota, with the gateway and schema compatibility as the contract between teams.\n- Adopt expand/contract database migrations so schema and code changes no longer have to ship together.\n- Replace the maintenance window with blue-green deployment on two identical stacks, traffic switched at the gateway and rollback performed by switching back.\n- Measure and publish the result: deployment lead time, deployment frequency per team, and the share of releases that needed no coordination with another team.", "dependencies": ["S2", "S3"]}, {"step_id": "S6", "title": "Seam-level verification: golden master, contracts, shadow diffing, reconciliation", "description": "Replaces the impossible goal of blanket test coverage with verification exactly where the cut will be made. A two-million-line monolith cannot reach 70% coverage in a year; a service boundary can be verified to a very high standard in weeks.\n\n- Build a characterization harness that records real production requests and replays them against the monolith, capturing full responses as a golden master. This is the safety net for every extraction.\n- Require every extracted service to pass the golden master on its public API before it takes live traffic, producing a diff report rather than a pass/fail.\n- Use consumer-driven contract tests between the monolith and each new service, and between services, so a change on one side breaks a build instead of production.\n- Run shadow traffic: mirror live requests to the new service, compare responses field by field, and gate the traffic ramp on the divergence rate.\n- Build per-module data reconciliation as a first-class test: row counts, checksums and business invariants compared on a schedule, with an owner and an alert threshold.\n- Add synthetic canary transactions that execute a real checkout, return and search every few minutes and alert on functional regression before customers notice.\n- Explicitly do not pursue blanket line coverage of the monolith. Track coverage only for newly written service code, where the target is 80%.", "dependencies": ["S2", "S3"]}, {"step_id": "S7", "title": "Data platform: schema ownership, join elimination, CDC, outbox, four-stage cutover playbook", "description": "The hardest part of the program and the part most plans under-specify. It does not depend on service extraction, so it starts in month one and runs in parallel with everything else.\n\n- Enforce ownership inside the database itself: one PostgreSQL role per module, able to write only its own schema and to read others only through defined views. Cross-schema writes are rejected by the database, not by convention.\n- Inventory every stored procedure, attribute it to one module, and either move it into that module's code or leave it as a module-private function. After a module is extracted, no stored procedure may touch two modules' tables.\n- Eliminate cross-module joins one at a time, replacing each with an API call, an event-fed materialized read model or a duplicated read-only projection. Track the count per module and drive it to zero before that module is cut.\n- Stand up change data capture with Debezium reading the PostgreSQL WAL into Kafka. This publishes monolith domain events with no application change, the lowest-risk start available.\n- Add a transactional outbox for new services so their events and their state changes commit together.\n- Adopt one reusable four-stage cutover playbook per module and apply it identically every time. Stage A: the service owns its schema logically, reads from CDC into its own store, and serves shadow traffic only. Stage B: reads cut over, the monolith stays system of record. Stage C: writes cut over, and the monolith's tables become read-only replicas fed by reverse CDC from the service. Stage D: old tables and dead code are dropped only after a full peak or four clean weeks, whichever is longer.\n- Make stage C genuinely reversible: because the sync direction can be flipped, rolling back a write cutover is a configuration change plus a reconciliation pass, not a data restore.\n- Build the reconciliation service now so every later cutover has an objective consistency check with thresholds and owners.\n- Schedule the 1.2 TB storage migration as background work: new services start on the existing cluster with their own schemas, and physical split happens only once a module is stable.", "dependencies": ["S2", "S3", "S6"]}, {"step_id": "S8", "title": "Extract Catalog and Search", "description": "First extraction, chosen because it is read-heavy, mostly isolated and carries no transactional risk. It also pays for itself: replacing the nightly Lucene rebuild with real-time indexing is a visible business win that buys political cover for the harder cuts.\n\n- Create a Catalog service owning product, category and media tables plus its own search index.\n- Feed it from CDC so product and price changes appear in search within seconds instead of after a nightly rebuild.\n- Route through the gateway behind a flag and ramp 1% → 5% → 25% → 50% → 100%, with the rollback controller able to revert to the monolith's internal Lucene path at any point.\n- Run shadow traffic and compare result sets before any live traffic, then keep the old index warm for two weeks after full cutover.\n- Verify the mobile app, which hits the same endpoints, inside the same ramp; its behaviour is part of the go/no-go.\n- Land this cut in an open delivery window and let it soak at least four weeks before the freeze.", "dependencies": ["S5", "S6", "S7"]}, {"step_id": "S9", "title": "Extract Returns as the first write-path and own-database proof", "description": "Second extraction and the first that owns writes and a database. Returns is chosen because it is off the peak-critical path, has modest coupling, and exercises the full four-stage playbook at low stakes.\n\n- Build the Returns service with its own schema, consuming order and customer events rather than joining their tables.\n- Run the playbook end to end: shadow reads, read cutover, then write cutover with reverse CDC keeping the monolith's tables current.\n- Prove the rollback path in a game day before write cutover, including a reconciliation pass and a re-run of the golden master.\n- Keep the back-office returns screens on the monolith for now, so staff workflow is untouched by this step.\n- Record every friction point and correct the playbook. The real output of this step is a proven, reusable procedure, not just one service.", "dependencies": ["S5", "S6", "S7"]}, {"step_id": "S10", "title": "Extract Inventory and replace the 15-minute warehouse file exchange", "description": "Removes one of the sharpest coupling points in the system and unblocks the checkout work. Inventory is extracted in parallel with the other early cuts because it couples the monolith to an external warehouse process rather than to other modules.\n\n- Build the Inventory service to ingest the warehouse feed directly and publish stock-level events.\n- Preserve the existing file-based interface for the first weeks, running the new ingest in parallel with the legacy feed and reconciling hourly until they agree.\n- Keep the monolith's inventory tables as a projection fed by events, so cart and checkout keep working unchanged during the cut.\n- Design reservation semantics now — reserve, confirm, release, with expiry — even though checkout is not yet extracted. The API is needed later and is cheap to get right here.\n- Load-test inventory ingest at 12x, because the warehouse feed schedule and the sales peaks do not always coincide.\n- Cut over reads first, then writes, with the rollback controller able to restore the file feed as the source of truth.", "dependencies": ["S5", "S6", "S7"]}, {"step_id": "S11", "title": "Extract Customer Accounts and Loyalty, with a conservative auth strategy", "description": "Extracts customer accounts and loyalty, including the authentication decision. Auth is the step that most often derails e-commerce migrations, so the auth path is deliberately moved last and guarded hardest.\n\n- Build the Customer service owning profile, address and loyalty tables, with country-specific loyalty rules expressed as data where possible and as code where not.\n- Keep authentication in the monolith for the first phase. Move token issuance only once customer data is stable, and never within four weeks of a freeze.\n- Introduce distributed session handling and a token-validation API so services can verify identity without querying the monolith database.\n- Cut over reads, then writes, with reverse CDC, validating against the golden master across all 8 countries and 4 languages.\n- Verify the mobile app's session behaviour explicitly, since it holds long-lived sessions the storefront does not.\n- Move loyalty point accrual and redemption last, because a loyalty error is a customer-visible financial error, not a technical incident.", "dependencies": ["S5", "S6", "S7", "S9"]}, {"step_id": "S12", "title": "Extract Cart", "description": "Extracts the cart, which is stateful and sits directly in front of checkout. It is done before pricing and checkout because both need a stable cart boundary to call.\n\n- Build the Cart service on Redis for session and line-item state, validating products and inventory through service calls rather than database joins.\n- Make every cart operation idempotent, because a retried add or remove during a peak must not duplicate a line item.\n- Keep the cart tables in the monolith as a read-only projection fed by events, for rollback and for the not-yet-migrated back-office screens.\n- Ramp traffic while monitoring cart abandonment rate as the business metric, since cart latency shows up as lost revenue rather than as errors.\n- Exercise anonymous and authenticated carts separately; they follow different paths and fail in different ways.\n- Land this cut in an open window with a full four-week soak before the freeze.", "dependencies": ["S8", "S10", "S11"]}, {"step_id": "S13", "title": "Extract Pricing and Promotions as an unchanged black box", "description": "Extracts the 200,000-line pricing module without rewriting it. The rules are not understood by anyone, so they are wrapped and characterized rather than reverse-engineered. Rule decomposition, documentation and a DSL are explicitly out of scope for these twelve months.\n\n- Build a golden master corpus from at least a million real historical pricing requests and their recorded outputs, covering all 8 countries, 3 currencies and 4 languages, plus every promotion type that can be discovered.\n- Refactor only the module's dependencies: pricing must obtain customer, product and inventory data through interfaces rather than direct database access, so it can be lifted out.\n- Move the pricing code into its own service unchanged, owning its tables after cutover, and expose a single decision API.\n- Run it in shadow mode for at least four weeks against live traffic, comparing every computed price with the monolith. Any divergence blocks the ramp.\n- Cut over behind a flag with per-country ramps, since a pricing error is a financial and legal exposure rather than a technical incident.\n- Keep the in-monolith evaluator available and warm as the rollback path for at least one full peak after cutover.\n- State in writing that rule decomposition is deferred to a follow-up program, so it does not creep back into this one.", "dependencies": ["S5", "S6", "S7"]}, {"step_id": "S14", "title": "Extract Payment under a stricter regime than anything else", "description": "Extracts payment processing, where mistakes are irreversible and regulatory. Payment is done before checkout orchestration, because checkout cannot be decomposed without a payment boundary already in place.\n\n- Build the Payment service owning the integration with the three providers, including tokenization, authorisation, capture, refund and provider webhooks.\n- Reduce PCI scope rather than expand it: no raw card data at rest in the new service, credentials in secrets management, no card data in logs or traces.\n- Make every payment operation idempotent with explicit idempotency keys, because retries at peak are normal and double charges are not recoverable.\n- Cut over provider by provider rather than all three at once, starting with the lowest-volume provider.\n- Run the golden master across all decline, timeout, partial-authorisation and refund scenarios, and rehearse the fallback to the monolith's direct provider integration.\n- Verify fraud detection and 3-D Secure paths explicitly, since they are usually the least covered and the most visible when they break.\n- Land this cut early in an open window so it soaks well before the freeze.", "dependencies": ["S5", "S6", "S7"]}, {"step_id": "S15", "title": "Extract Order Management with an explicit state machine", "description": "Extracts order management as the record of truth for the order lifecycle, after the services it depends on exist and are stable.\n\n- Build the Order service with its own database and an explicit order state machine that validates every transition.\n- Introduce event sourcing for order status so the audit trail satisfies regulators and fulfilment teams, and so state can be rebuilt after an incident.\n- Consume events from payment, inventory and returns rather than polling or joining.\n- Cut over reads first for the five teams that query orders, then writes, keeping the monolith's order tables as a reverse-CDC projection.\n- Reconcile order counts and monetary totals hourly against the monolith throughout the transition. A monetary mismatch is an immediate rollback, not a ticket.\n- Load-test concurrent order state transitions at peak, since the state machine becomes the new serialisation point.", "dependencies": ["S9", "S10", "S13", "S14"]}, {"step_id": "S16", "title": "Compose Checkout from independent services using a saga", "description": "The highest-risk cut in the program, deliberately placed last among the transactional work and only after the components it orchestrates are individually proven.\n\n- Build an orchestrating Checkout service that performs: cart validation, price computation, inventory reservation, payment authorisation, order creation.\n- Implement compensating actions for every step: a failed authorisation releases the inventory reservation; a failed order creation voids the authorisation.\n- Require idempotency keys end to end so a retried checkout cannot double-charge or double-reserve.\n- Handle timeouts explicitly, including the peak case where inventory or pricing is slow. The saga must fail safe to a retryable state, never to a half-committed order.\n- Mirror live checkout traffic to the new orchestration and compare full outcomes, including order totals and reservations, before any live traffic.\n- Ramp live traffic during an open window only, and keep the monolith's checkout path fully functional and warm for rollback until it has survived a peak.\n- Hold the six-week peak-readiness gate before this ramp and treat a failed gate as a stop, not a delay.", "dependencies": ["S12", "S13", "S14", "S15"]}, {"step_id": "S17", "title": "Migrate back-office, storefront and mobile clients off the monolith database", "description": "Moves the clients and the 300 back-office users onto the service APIs. Until this happens, the monolith's database remains a dependency even where the logic has already moved.\n\n- Refactor back-office screens to consume service APIs through the gateway, replacing direct SQL access table by table, starting with orders and customers.\n- Add aggregation endpoints where a screen needs several services, plus a short-lived cache so 300 staff do not multiply load on the new services.\n- Update the server-rendered storefront to call service APIs while keeping the existing rendering path working behind a flag, so a rendering regression is a flag flip rather than a rollback.\n- Point the mobile app at the gateway for migrated endpoints while keeping the old endpoints alive for un-updated app versions, since users do not upgrade on your schedule.\n- Publish API versioning rules and deprecation windows so teams can change their services without coordinating with client releases.\n- Load-test back-office behaviour with 300 concurrent staff on top of peak storefront traffic, since the two now share services.", "dependencies": ["S16"]}, {"step_id": "S18", "title": "Decommission the monolith core and harden for the second peak", "description": "Removes what is left of the monolith and proves the new architecture survives a peak. This step is as much about proving the state is coherent as about deleting code.\n\n- Delete dead code and dropped tables module by module, only after a module has run a full peak or four clean weeks, whichever is longer.\n- Keep read-only access to the old database for a defined period for historical and regulatory queries, then archive and decommission it.\n- Replace the monolith's remaining cross-module reads with service calls or event-fed projections. The monolith should now be a small set of modules, or nothing at all.\n- Re-run the full 12x load test against the new topology across all 8 countries, 3 currencies and 4 languages, and tune autoscaling, connection pools and broker partitions from the results.\n- Run chaos game days: kill each service in turn and confirm the storefront degrades gracefully rather than failing completely.\n- Confirm the peak-readiness gate before the second peak and publish its evidence. A failed gate defers remaining work rather than risking the peak.\n- Write the exit report: final service boundaries, data ownership, runbooks, SLO history, the scope-ladder rung actually reached, and the list of work explicitly deferred to a follow-up program.", "dependencies": ["S17"]}], "estimated_complexity": "high", "success_metrics": "- Independent deployability: 100% of releases to extracted services require no coordination with another team and no monolith release, demonstrated for at least 6 services by month 9.\n- Independent deployability precedes extraction: at least 4 of the 5 teams release their own artefacts without being separate services by month 5.\n- The 30-minute maintenance window is retired by month 6; no release after that date requires a planned outage.\n- Deployment lead time from merge to production for a single service is 30 minutes or less, and each team releases at least 3 times per week by month 6.\n- Zero unplanned downtime attributable to the migration across the 12 months; platform availability of 99.95% or better inside each peak window.\n- Both January and July peaks pass with no migration-caused incident: 12x baseline load sustained, checkout p99 under 5 seconds, error rate under 0.5%, no queue backlog beyond 5 minutes.\n- 100% of migration increments that reach production have a rollback demonstrated in a game day and executable in under 30 minutes.\n- Hourly data reconciliation shows under 0.001% discrepancy on row counts and checksums per module, with zero unexplained business-invariant violations.\n- Cross-module database joins and cross-module writes originating in application code are zero for every module at the moment it is extracted, enforced by database roles and CI checks rather than by review.\n- Pricing parity: 100% agreement with the golden master on a corpus of at least 1,000,000 historical requests across all 8 countries, 3 currencies and 4 languages, both before and after cutover.\n- Stored procedures touching more than one module's tables: zero for every extracted module.\n- Search freshness improves from a nightly rebuild to under 30 seconds between a product change and its visibility in search results.\n- Warehouse inventory freshness improves from 15 minutes to under 2 minutes end to end.\n- 100% of public APIs of extracted services have golden-master or consumer-driven contract coverage; line coverage is tracked only for newly written service code, where it reaches 80%.\n- The peak-readiness gate is passed with published evidence six weeks before both peaks, covering 100% of its defined checks.\n- Scope ladder rungs 1–6 are complete within 12 months, or the program stops at a rung boundary in a documented, coherent, peak-safe state."}The proposal expanded to 12 steps, adding crucial operational layers like strategic freeze planning and core infrastructure setup. It successfully integrated the black-box pricing strategy and CDC patterns, making it much more realistic than its previous version. However, it still lacks the deep data-cutover mechanics and strict calendar enforcement seen in Proposal 2.
- Added explicit mobilization and strategic freeze planning to protect January and July peaks.
- Introduced the Golden Master characterization test harness and replay engine.
- Detailed the Anti-Corruption layer with CDC and Outbox patterns to decouple the database.
- Still omits a detailed, reusable data cutover playbook like the one in Proposal 2.
- The Anti-Corruption Layer step mixes CDC and read-only replicas in a way that does not clearly resolve the shared database problem.
- Proposal 1 : Explicit peak-season window planning and extracting pricing as-is.
- Proposal 2 : Strangler Fig Facade at the API gateway and stored procedure refactoring.
- Proposal 1 : Extracting Search after building the pipeline, and refactoring pricing rules in Phase 2.
- Proposal 2 : Extracting Inventory as the seventh step and Pricing after Order Management.
+ Mobilization and Strategic Freeze Planning+ Target Architecture and Domain Boundaries+ Core Infrastructure and Observability Foundation+ Test Harness: 'Golden Master' Characterization+ Extraction 2: Customer Identity and Profile+ Database Decoupling: The 'Anti-Corruption' Layer+ Extraction 3: Inventory and Fulfillment Interface+ Extraction 5: Checkout Orchestrator (Saga Pattern)+ Final Monolith Decomposition and Clean-up+ Peak Season Stress Test and HandoverMobilize Program and Define Target ArchitectureBuild Platform Foundation for Independent DeploymentsImplement Strangler Fig Facade and Monolith InstrumentationEstablish Continuous Delivery and Test AutomationExtract Customer Accounts and Loyalty ServiceExtract Inventory ServiceExtract Returns ServicePeak Season Readiness and Resilience EngineeringExtract Cart ServiceExtract Order Management and Checkout OrchestrationDatabase Decomposition and Stored Procedure RefactoringReorganize Teams for Independent DeploymentPost-Migration Optimization and Monolith Decommissioning
The plan produced
1. Mobilization and Strategic Freeze Planning new
Establish the governance and safety constraints for the migration. This step defines the 'no-touch' windows around peak seasons (January and July) and sets up the steering committee to manage the complexity of a 2M LOC codebase.
- Team Alignment: Reorganize the 5 teams into 'Service-First' pods. Each pod owns a target service extraction alongside their monolith maintenance duties.
- Risk Framework: Define strict 'Freeze Windows' (e.g., Dec 15–Jan 15, June 15–July 15) where no architectural changes are permitted, only bug fixes.
- Dependency Mapping: Create a 'Coupling Heatmap' identifying the most entangled modules (likely Pricing and Checkout) to isolate them for later phases.
2. Target Architecture and Domain Boundaries (after 1) new
Perform rigorous Domain-Driven Design (DDD) to define service boundaries. Given the 2M LOC and 350 tables, abstracting the domain is critical to prevent 'distributed monolith' outcomes.
- Strategic DDD: Map current modules to bounded contexts (Catalogue, Pricing, Orders, Identity, Fulfillment).
- Database Decomposition Design: Define the target data model for each service. Explicitly list which of the 350 tables move to which service and which cross-module joins must be replaced by API calls or events.
- Contract Definition: Draft API contracts (OpenAPI/GraphQL) for the core services to ensure backward compatibility with the existing frontend.
3. Core Infrastructure and Observability Foundation (after 1)
Build the 'platform' that allows services to exist independently. You cannot safely extract services without first having the tools to see, test, and deploy them individually.
- Kubernetes Cluster: Provision a production-grade K8s environment with strict namespace isolation.
- API Gateway: Deploy a robust API Gateway (e.g., Kong, AWS ALB) to sit in front of the monolith. This is the 'Traffic Switcher' for the Strangler Fig pattern.
- Observability Stack: Implement Distributed Tracing (Jaeger), Centralized Logging (ELK/Loki), and Metrics (Prometheus). You must be able to trace a request from the gateway through a new service and back to the monolith.
- CI/CD Pipelines: Create independent deployment pipelines for services, allowing 15-minute rollback capabilities distinct from the monolith's 2-week cycle.
4. Test Harness: 'Golden Master' Characterization (after 3) new
Since testing the new logic against the old logic is the primary validation method, create an automated regression suite that captures the 'current truth' of the legacy system.
-
Input Logging: Configure the monolith to log all incoming requests (and their responses) to a secure data lake, anonymizing PII.
-
Replay Engine: Build a tool that takes a captured legacy request, sends it to both the legacy monolith and the new service, and diffs the responses.
-
Coverage Baseline: Establish a 100% test coverage requirement for the interfaces being extracted. If you extract 'Search', you must have a test for every possible search query variant currently supported.
-
5. Extraction 1: Catalogue and Read-Only Search (after 4) from P2 step 5
The 'Low Hanging Fruit'. Extract the read-only Catalogue and Search capabilities first. This builds confidence and proves the Strangler Fig pattern without touching transactional data.
- New Service: Build 'Catalogue Service' that reads from a replicated Postgres (via logical replication) or a dedicated search DB (Elasticsearch).
- Traffic Shift: Configure the API Gateway to route
/productsand/searchrequests to the new service. - Fallback: If the service fails, the gateway should immediately reroute to the legacy monolith (circuit breaker).
- Optimization: Replace the nightly Lucene rebuild with real-time indexing to instantly reflect price/inventory changes.
6. Extraction 2: Customer Identity and Profile (after 5)
Extract user data handling. This decouples the 'who' from the 'what' (purchases), allowing independent authentication scaling.
- Account Service: Move user tables (Login, Profile, Address) to a dedicated service.
- Session Migration: Implement a token-passing strategy where the legacy monolith trusts tokens generated by the new Identity Service.
- Read-Through Cache: The legacy monolith should stop querying the user table directly; instead, it fetches user details from the Identity Service via an internal REST call or cached event.
- Rollback: Keep a 'sync-back' script to ensure if users are created in the new service, the legacy DB knows about them during the transition period.
7. Database Decoupling: The 'Anti-Corruption' Layer (after 3, 5) new
The most dangerous step. Breaking the 1.2TB DB entanglement requires intercepting the stored procedures. We stop writing to the shared DB from new services.
- CDC Implementation: Deploy Debezium to capture Postgres Write-Ahead Logs (WAL) into Kafka. This allows new services to be notified when the monolith updates data.
- Outbox Pattern: Refactor the monolith code so that when it writes to the DB, it also writes a 'domain event' to an internal Outbox table, which Debezium then publishes.
- Read-Only Replicas: Force new services to read from read-only replicas of the legacy DB to prevent them from causing lock contention on the master.
8. Extraction 3: Inventory and Fulfillment Interface (after 7)
Move the inventory logic out. This separates the 'Stock' truth from the 'Order' truth, preparing for the complex checkout.
- Inventory Service: Create a service to hold the 'Single Source of Truth' for current stock levels.
- Legacy Integration: The monolith's checkout flow must now ask the Inventory Service to 'Reserve Stock' before processing payment.
- Warehouse Sync: Move the 15-minute file exchange logic into this service, isolating the legacy code from warehouse connectivity issues.
- Concurrency Handling: Implement optimistic locking in this service to handle high-concurrency 'reserve' requests during sales.
9. Extraction 4: Pricing and Promotions (The 'Black Box') (after 8) from P2 step 12
Extract the 200,000 LOC pricing engine. Do not rewrite the logic yet; wrap it. This is a 'Strangler Fig' step, not a refactoring step.
- Encapsulation: Move the existing pricing code (and its dependencies) into a new Spring Boot project called 'Pricing Service'.
- Dependency Injection: Replace direct DB access within the pricing logic with interfaces that call the Catalogue and Customer services via API.
- Performance Parity: Ensure the latency added by moving pricing to a separate network call is negligible (<50ms). Cache aggressively at the service level.
- Validation: Use the Golden Master (S4) to replay all historical orders and verify the new service returns the exact same price down to the cent.
10. Extraction 5: Checkout Orchestrator (Saga Pattern) (after 9) new
Replace the monolithic transaction with a distributed saga. This is the final piece of the transactional flow.
- Orchestrator: Build a lightweight service that coordinates the 'Checkout' process.
- Saga Logic: When an order is placed: 1. Call Pricing Service. 2. Call Inventory Service (Reserve). 3. Call Payment Gateway (External). 4. Call Order Service (Create).
- Compensation: If step 4 fails, the Orchestrator triggers 'Cancel Reserve' on the Inventory Service and 'Void' on the Payment Gateway.
- Legacy Cutoff: The monolith's 'Checkout' screen is replaced by a frontend form that calls this Orchestrator API.
11. Final Monolith Decomposition and Clean-up (after 10) new
At this stage, the monolith is hollowed out, containing mostly code that is called by the new services or legacy admin functions.
- Admin Panel: Move back-office functionality (Order management, Refunds) into a 'Management Service' that reads from the new event streams.
- Code Deletion: Delete the code for the extracted domains (Pricing, Search, Cart) from the monolith repository to enforce boundaries.
- Database Cleanup: Drop the tables owned by new services from the legacy monolith database.
- Performance Tuning: Optimize the remaining monolith for the only things it does: serving legacy redirects and perhaps a few 'orphaned' modules.
12. Peak Season Stress Test and Handover (after 11) new
Prepare for the high-volume events in Jan/July. Validate the new architecture holds under pressure.
- Chaos Engineering: Randomly kill the Search or Inventory services and verify the site degrades gracefully (e.g., 'Search temporarily unavailable') without crashing the checkout.
- Load Testing: Simulate 12x peak traffic using tools like Gatling/JMeter against the new APIs.
- Runbooks: Finalize operational playbooks for every team. Who owns what? How to restart a dead service? How to fallback to the monolith if the database fails?
- Zero Downtime: 100% availability maintained throughout the 12-month migration, excluding planned maintenance windows.
- Rollback Speed: Every service deployment is reversible in < 10 minutes via automated traffic switching at the Gateway.
- Peak Performance: The new architecture sustains 12x baseline load (480k orders/day) with < 200ms P95 latency for Checkout.
- Data Integrity: Zero discrepancies between pricing calculations of the old monolith and the new Pricing Service across 1 million replayed requests.
- Independence: Teams successfully deploy their services on a weekly cadence without coordinating with the monolith's bi-weekly release.
[SYSTEM]
You are an expert assistant in complex project planning.
Your task is to generate a detailed and structured action plan to reach the main objective in the most professional and most detailed way, no matter how much work or steps will be needed to perform.
Use your internal reasoning processes to think deeply about the problem and create the most comprehensive plan possible.
Take as much time and space as you need to think through all aspects of the problem.
After your thorough analysis, answer with the plan in the requested structure.
Every text field you write will be read by a busy person, so write for them: short sentences, one idea each, in short paragraphs. Text fields accept Markdown: separate paragraphs with a blank line, use a bullet list when you enumerate things and plain paragraphs when you explain or argue, and bold at most one key phrase per paragraph. A text of more than three sentences must be split into paragraphs; never deliver a single unbroken block of text.
[HUMAN]
Main Objective: "A mid-size European fashion retailer runs its e-commerce on a 10-year-old monolith: Java 8 / Spring, about 2 million lines, one PostgreSQL database of 1.2 TB with 350 tables and heavy use of stored procedures and cross-module joins. It serves 8 countries, 3 currencies and 4 languages, with about 40,000 orders a day and peaks of 12x during sales. The monolith contains: the storefront (server-rendered, plus a separate mobile app hitting the same endpoints), catalogue and search (a Lucene index rebuilt nightly), pricing and promotions (the most complex module, 200,000 lines, with country-specific rules nobody fully understands), cart and checkout with three payment providers, order management, inventory synchronised every 15 minutes with the warehouse system via file exchange, customer accounts and loyalty, returns, and a back-office used by 300 staff. Deployments happen every two weeks as a single artefact with a 30-minute maintenance window; test coverage is 25% and mostly unit tests. Five teams of 8 developers, each organised around a business area but all committing to the same repository.
Plan the migration to independently deployable services over 12 months with no feature freeze, no unplanned downtime and the ability to roll back every step, preserving the peak-season capacity (sales in January and July must not be put at risk)."
For your consideration and refinement, here are proposals from the previous round:
Previous Proposal 1 (ID: 1a154427-5ec4-44d9-aff2-f7dd482a0601, Agent: claudeHaiku4.5_initial_1, LLM: anthropic/claude-haiku-4-5):
Estimated Complexity: high
Success Metrics: - All 8 services independently deployed and running in production with zero unplanned downtime during 12-month migration
- Zero data inconsistencies between service-specific databases (validated by monthly reconciliation)
- January and July peak seasons proceed with no degradation: 480k orders/day processed within 5-second checkout SLA
- Test coverage increased from 25% to 70%+ for all extracted services
- Every service deployment is fully automated; manual rollback procedures tested and <30 minutes to execute
- Order processing latency (cart → confirmation) unchanged or improved: maintained under 5 seconds at peak load
- All 5 teams deploying independently: no cross-team deployment coordination required after cutover
- Pricing/promotions service successfully extracted with all 200k LOC of country-specific rules preserved and validated
- Search latency improved or maintained despite architectural change
- Inventory synchronization with warehouse continues reliably: no missed 15-minute sync cycles
- Back-office operations for 300 staff members unaffected by migration; service aggregation endpoints maintain <500ms latency
- Zero payment processing regressions: all three payment providers functioning, fraud detection active, PCI-DSS compliance maintained
Steps (24):
1. Current State Documentation & Target Architecture
Create a detailed map of the monolith to inform service extraction strategy.
- Audit all modules: storefront, catalogue, search, pricing/promotions, cart, checkout, orders, inventory, customers, loyalty, returns, back-office
- Map dependencies between modules, identifying cross-module calls and data flows
- Model future bounded contexts using Domain-Driven Design
- Create technology inventory (libraries, frameworks, protocols)
- Document interface contracts for each module
- Identify which teams own which modules for organizational alignment
2. Data Dependency Analysis & Dual-Write Strategy (depends on: 1)
Untangle the 1.2TB database to support service independence without blocking progress.
- Map all 350 tables to future service domains
- Identify cross-service joins and stored procedures that span domains
- Design per-service database schemas with minimal denormalization
- Create data versioning framework to support rollback
- Plan dual-write patterns: how old monolith and new services will sync during transition
- Document eventual-consistency requirements and conflict resolution
- Design data migration runbooks with clear rollback steps
3. Test Coverage Audit & Improvement Roadmap (depends on: 1)
Build confidence for service extraction by eliminating test blindness.
- Audit current 25% test coverage by module
- Identify coverage gaps in modules scheduled for early extraction
- Establish target of 70%+ coverage for modules being extracted
- Prioritize integration tests over unit tests given monolith complexity
- Create quality gates: no service extraction below 60% module coverage
- Plan for continuous improvement during extraction phases
4. Peak-Season Window Planning & Risk Framework (depends on: 1)
Protect January and July sales by scheduling extractions during safe windows.
- Map annual peak periods: January sales (peak orders), July sales, plus any promotional events
- Define 4-week freeze windows before/during peaks
- Identify lowest-risk windows in each month for major changes
- Create rollback procedures that execute in <30 minutes
- Establish monitoring escalation for changes made near peak season
- Document communication plan with business teams
5. Observability Foundation Setup
Instrument the system for real-time visibility during migration.
- Deploy centralized logging (ELK, Splunk, or similar)
- Set up metrics collection (Prometheus, Datadog, or similar)
- Implement distributed tracing (Jaeger, Zipkin) for request flows across services
- Create dashboards for: requests/sec, error rates, latency percentiles, database load
- Define SLOs: order processing latency p99, checkout success rate, payment authorization speed
- Set up alerts for SLO violations and anomalies
6. Feature Flags, Containerization & API Gateway
Build the technical foundation for canary deployments and controlled traffic routing.
- Implement feature flag system (LaunchDarkly, custom Spring Boot solution, etc.)
- Containerize monolith and all new services (Docker)
- Set up container orchestration (Kubernetes or similar) with service templates
- Deploy API gateway (Kong, AWS ALB) with routing rules
- Implement service-to-service authentication (mTLS, JWT)
- Configure rate limiting and circuit breakers at gateway
7. Deployment Pipeline & Automated Rollback (depends on: 6)
Enable safe, automated deployments with reliable rollback capability.
- Implement CI/CD pipeline with automated testing gates
- Set up blue-green deployment: run old and new versions in parallel, switch traffic atomically
- Build canary deployment capability: route 5%→10%→50%→100% of traffic gradually
- Automate rollback: trigger on error rate threshold, latency spike, or manual command
- Create deployment runbooks for each service
- All deployments must be independent; monolith keeps 2-week cycle until fully extracted
8. Test Coverage Improvement to 70%+ (depends on: 3)
Close test gaps before extracting services to reduce rollback risk.
- Implement integration tests for key flows: order creation, payment processing, inventory updates
- Add contract tests between modules to catch breaking changes
- Use mutation testing to verify test quality
- Target 70%+ coverage for: pricing module, payment module, order management
- Establish automated quality gates: coverage <70% blocks extraction of that service
- Include tests for peak-load scenarios (40k→480k orders)
9. Search/Catalogue Service Extraction & Validation (depends on: 7, 8, 3)
Extract the first service: search is read-heavy, isolated, and low-risk.
- Extract catalogue and search indexing logic from monolith
- Build as independent Spring Boot service with own codebase/deployment
- Create new database schema for catalogue (subset of 350 tables)
- Implement dual-write: monolith writes to both old Lucene index and new service
- Implement canary routing: API gateway sends 10% of search requests to new service, monitor latency and correctness
- Validate results match between old and new service (checksums on result sets)
- Gradually increase traffic: 10%→25%→50%→100%
- Keep dual-write active for 2 weeks post-cutover for rollback safety
10. Event Bus & Service Mesh Infrastructure (depends on: 9)
Build async communication layer required for multi-service coordination.
- Deploy message broker (Kafka recommended for ordering guarantees and peak load of 40k/sec)
- Define domain events: OrderPlaced, PaymentAuthorized, InventoryReserved, etc.
- Implement event schema versioning and compatibility
- Set up service discovery (Consul, Kubernetes DNS)
- Implement distributed configuration management
- Create event publishing library for services to use
- Document saga patterns for multi-step workflows
- Test message broker under peak load (480k messages/day)
11. Inventory Service Extraction & Warehouse Sync (depends on: 10)
Extract inventory as second service: well-bounded, drives warehouse sync complexity.
- Extract inventory logic and reservation system
- Build inventory service with own database schema
- Implement dual-write from monolith to both old and new inventory data
- Preserve existing 15-minute warehouse file exchange, but now via service
- Create inventory events: ReservationCreated, ReleaseRequested
- Implement canary rollout: gradual traffic shift like search service
- Test warehouse sync under peak load
- Validate inventory consistency across monolith and new service before full cutover
12. Customer/Loyalty Service Extraction & Auth Refactoring (depends on: 10)
Extract customer accounts and loyalty: enables independent scaling of auth layer.
- Extract customer account and loyalty program logic
- Build customer service with own database schema
- Separate authentication from monolith: implement API for token validation
- Support multi-tenant loyalty rules (8 countries, country-specific points rules)
- Implement canary rollout with real customer sessions
- Create backwards-compatible customer APIs
- Test account operations at peak concurrency (concurrent logins, loyalty point updates)
- Plan for session management: ensure distributed sessions work across services
13. Saga Pattern Library & Order Orchestration Framework (depends on: 10)
Build the framework for managing distributed transactions across services.
- Implement saga pattern library: choreography-based (event-driven) and orchestration-based patterns
- Support compensating transactions: if payment fails, return inventory reservation
- Handle timeouts and retries with exponential backoff
- Implement idempotency keys to prevent duplicate charges on retries
- Test saga execution under peak load and network failures
- Document patterns for: order placement saga, payment saga, return saga
- Create distributed tracing for saga flows
14. Pricing/Promotions Service Extraction (Phase 1: Extract As-Is) (depends on: 13)
Begin extraction of most complex module (200k LOC) without initial refactoring.
- Extract pricing engine as-is with minimal refactoring to reduce initial risk
- Preserve all country-specific rules and business logic
- Build service boundary: accept pricing requests, return prices/promotions
- Create feature tests that document all 200k LOC behavior
- Map all promotion types to test scenarios
- Test with real country/currency/language combinations
- Implement as service behind same interface initially
- Prepare for Phase 2 refactoring once stable in production
15. Pricing/Promotions Service Refinement (Phase 2: Rules Refactoring) (depends on: 14)
Gradually improve pricing service maintainability without breaking production.
- Document the 200k LOC of complex rules in machine-readable format
- Refactor rules engine into composable components
- Build DSL for country-specific promotion rules
- Decompose monolithic rule evaluation into smaller decision trees
- Use feature flags to A/B test refactored rules vs old implementation
- Optimize performance: reduce calculation time for promotions at checkout
- Validate that refactored logic matches original behavior across all countries
16. Payment Service Extraction & Security Hardening (depends on: 13)
Extract payment processing with extreme rigor given PCI/regulatory requirements.
- Separate payment logic from checkout: payment validation, three-provider integration
- Build payment service with encrypted credential storage, no raw card data in logs
- Implement fraud detection integration and decline handling
- Audit for PCI-DSS compliance: minimal data exposure, encrypted transport
- Implement E2E testing for all three payment provider scenarios
- Load test payment service: 500+ payments/sec at peak
- Implement idempotent payment requests: prevent double-charging on failures
- Create detailed rollback procedures: how to fall back to direct monolith payment handling
17. Order Service Extraction & Event Stream (depends on: 13, 16)
Extract order management: central service coordinating multiple workflows.
- Extract order creation, status tracking, and management logic
- Build order service with event stream: OrderCreated, PaymentAuthorized, InventoryReserved, OrderConfirmed
- Support order querying by all 5 teams (inventory, fulfillment, customer service, etc.)
- Implement order event sourcing for audit trail and replay capability
- Create order state machine: validate state transitions
- Test concurrent order processing at peak load (40k orders/day)
18. Checkout Service Composition via Saga (depends on: 17)
Compose checkout from independent payment, inventory, and order services using sagas.
- Build checkout service that orchestrates: cart validation → pricing calculation → inventory reservation → payment authorization → order creation
- Use saga pattern: if payment fails, release inventory reservation automatically
- Implement distributed transaction semantics: all-or-nothing guarantee
- Support three payment providers transparently
- Test all failure scenarios: payment declines, inventory unavailable, warehouse system down
- Implement timeout handling: what happens if inventory service is slow at peak
- Validate checkout latency remains <5 seconds at peak load
19. Back-Office Integration with Service APIs (depends on: 18)
Update back-office (used by 300 staff) to coordinate across all services.
- Create service aggregation endpoints: orders endpoint calls order service + payment service + inventory service
- Update back-office UI to call new service APIs instead of monolith
- Implement service discovery: handle service availability transparently
- Create caching layer: reduce latency for frequently accessed data
- Test with 300 concurrent staff users
- Implement search across all orders/customers via service APIs
- Add retry logic and timeouts to handle service failures gracefully
20. Storefront & Mobile App Refactoring (depends on: 19)
Update client applications to use new service architecture transparently.
- Update server-rendered storefront templates to call service APIs
- Update mobile app endpoints (already separate, now points to services via gateway)
- Implement client-side caching: reduce latency impact of distributed calls
- Maintain backwards compatibility: old clients must still work
- Update API versioning: enable service changes without breaking clients
- Implement request tracing: correlate user requests across services
- Test storefront and mobile under peak load scenario (480k orders/day)
21. Legacy Database Deprecation & Data Migration (depends on: 20)
Safely decommission the monolith database once all services are independent.
- Verify all data has been migrated to service-specific databases
- Maintain 2-week read-only access to old database for emergency queries
- Archive old database snapshots (regulatory requirement for order history)
- Update backup/recovery procedures: now per-service instead of monolith
- Verify no remaining cross-service joins depend on monolith schema
- Document data mapping for future reference
- Decommission old database infrastructure
22. Load Testing & Performance Optimization (depends on: 21)
Validate new architecture meets production capacity requirements.
- Simulate peak load scenario: 480k orders/day (40k baseline × 12)
- Test across 8 countries, 3 currencies, 4 languages simultaneously
- Identify bottlenecks: service latency, database query performance, message broker throughput
- Optimize hot paths: pricing calculations, search queries, payment processing
- Test cache effectiveness: Lucene search response times, pricing cache hit rates
- Validate database connection pools don't exhaust under peak load
- Create load testing environment: realistic data, all 5 teams' concurrent usage
23. Documentation & Knowledge Transfer (depends on: 22)
Codify migration experience and new architecture for long-term success.
- Document final service boundaries: APIs, responsibilities, data ownership
- Create operational runbooks: how to deploy each service, how to handle common failures
- Record architecture decision log: why services were split this way
- Document data consistency model: eventual consistency patterns used
- Create troubleshooting guides: common issues and resolutions
- Train each team on their service and API contracts with other services
- Record key decisions and trade-offs (e.g., why search is separate from catalogue, why pricing is monolithic within its service)
24. Production Stabilization & 30-Day Monitoring (depends on: 23)
Establish stable operation and prove architecture meets requirements.
- Run 30-day monitoring period observing: error rates, latency, resource utilization
- Establish performance baselines: P99 latency per service, throughput, error rates
- Document SLO achievements: order processing speed, payment success rate, search latency
- Create incident playbooks based on observed issues
- Validate peak-load handling (Jan/July sales go normally through new architecture)
- Establish team on-call procedures for service alerts
- Plan for service scaling: autoscaling policies, capacity planning
- Complete full rollback verification: ensure rollback to monolith is always possible
Previous Proposal 2 (ID: f92888a9-2fa0-4ee5-a4ab-426fc426ffab, Agent: deepseek-flash_initial_2, LLM: deepseek/deepseek-flash):
Estimated Complexity: high
Success Metrics: - 100% of planned service extractions completed within 12 months.
- Zero unplanned downtime during January and July peak sales.
- All new services independently deployable with <5 minute lead time.
- 100% of deployments rollback-able within 5 minutes.
- 80% of traffic served by new services by end of 12 months.
- Test coverage increased to 60% for critical modules.
- Deployment frequency increased from bi-weekly to daily.
- Mean time to recovery (MTTR) < 30 minutes.
- Change failure rate < 15%.
- All stored procedures refactored or migrated to services.
- Database decomposed into 5+ independent databases.
- Peak load capacity sustained at 12x with <1% error rate.
Steps (15):
1. Mobilize Program and Define Target Architecture
Launch the migration program and define the target architecture. This step sets the foundation for all subsequent work.
Key activities:
- Establish a steering committee with business, architecture, and operations representatives.
- Conduct domain-driven design workshops to identify bounded contexts and service candidates.
- Define the target architecture: API gateway, service mesh, event-driven integration, and data ownership per service.
- Prioritize service extraction based on business value, risk, and coupling.
- Create architecture decision records (ADRs) and a service roadmap.
Output: a shared vision and prioritized backlog for the migration.
2. Build Platform Foundation for Independent Deployments (depends on: 1)
Build the platform foundation required for independent deployments. This includes infrastructure, tooling, and golden paths.
Key activities:
- Provision a Kubernetes cluster with namespaces for each service.
- Set up CI/CD pipelines per service using GitLab CI or ArgoCD.
- Deploy an API gateway (e.g., Kong) and service mesh (e.g., Istio) for traffic management.
- Implement observability: centralized logging (ELK), metrics (Prometheus/Grafana), and tracing (Jaeger).
- Set up secrets management (Vault) and configuration management.
- Create golden path templates for new services to reduce boilerplate.
Output: a production-ready platform where teams can deploy services independently.
3. Implement Strangler Fig Facade and Monolith Instrumentation (depends on: 2)
Implement the strangler fig facade and instrument the monolith. This allows incremental migration without disrupting users.
Key activities:
- Deploy the API gateway to route requests to the monolith or new services based on path or header.
- Modify the monolith to expose REST APIs for key domains (e.g., catalogue, customer).
- Implement the transactional outbox pattern to publish domain events from the monolith.
- Set up change data capture (CDC) from the monolith PostgreSQL to Kafka using Debezium.
- Introduce feature flags for routing and canary releases.
- Ensure all changes are backward compatible and can be rolled back.
Output: a facade that enables gradual traffic shifting and a data pipeline for synchronization.
4. Establish Continuous Delivery and Test Automation (depends on: 1)
Establish continuous delivery and test automation to support safe, frequent deployments.
Key activities:
- Increase automated test coverage for critical monolith modules (target 60%).
- Implement consumer-driven contract testing (Pact) between monolith and new services.
- Set up automated regression test suites for end-to-end flows.
- Integrate tests into CI/CD pipelines with quality gates.
- Enable blue-green and canary deployments for both monolith and services.
Output: a reliable deployment pipeline that supports rollback and rapid feedback.
5. Extract Catalogue and Search Service (depends on: 3, 4)
Extract the Catalogue and Search service. This is a read-heavy, low-coupling module, making it a good first candidate.
Key activities:
- Create a new Catalogue service with its own datastore (PostgreSQL for product data, Elasticsearch for search).
- Implement data synchronization from the monolith via CDC and events.
- Migrate read APIs for product listing and search to the new service via the gateway.
- Use feature flags to gradually shift traffic, with fallback to the monolith.
- Monitor performance and rollback if issues arise.
Output: an independently deployable Catalogue service serving a portion of traffic.
6. Extract Customer Accounts and Loyalty Service (depends on: 3, 4, 5)
Extract the Customer Accounts and Loyalty service. This service manages profiles, addresses, and loyalty points.
Key activities:
- Create a new Customer service with its own database.
- Synchronize data from the monolith via events (customer created, updated).
- Migrate profile management and loyalty APIs to the new service.
- Keep authentication in the monolith initially to reduce risk.
- Redirect customer API calls to the new service gradually.
Output: an independently deployable Customer service with data ownership.
7. Extract Inventory Service (depends on: 3, 4)
Extract the Inventory service. This service consumes the warehouse file feed directly and maintains real-time inventory.
Key activities:
- Create an Inventory service that reads the warehouse file feed (SFTP) and parses it.
- Publish inventory update events to Kafka.
- Migrate inventory queries from the monolith to the new service.
- Ensure the monolith and other services consume inventory events instead of querying the monolith DB.
Output: an independently deployable Inventory service with real-time updates.
8. Extract Returns Service (depends on: 3, 4, 6)
Extract the Returns service. This module is relatively independent and can be extracted early.
Key activities:
- Create a Returns service with its own database.
- Consume order and customer events to validate returns.
- Migrate returns UI and APIs to the new service.
- Ensure integration with order management for refunds.
Output: an independently deployable Returns service.
9. Peak Season Readiness and Resilience Engineering (depends on: 1)
Prepare for peak seasons and implement resilience engineering. This is critical to avoid downtime during January and July sales.
Key activities:
- Conduct load testing for 12x peak on new services and the monolith.
- Implement circuit breakers, bulkheads, rate limiting, and auto-scaling.
- Define change freeze periods: one month before and during January and July sales.
- Plan migration activities outside freeze windows.
- Run game days for failure scenarios and rollback drills.
Output: a system that can withstand peak loads and a schedule that protects peak seasons.
10. Extract Cart Service (depends on: 3, 4, 7)
Extract the Cart service. The cart is a stateful component that requires careful handling.
Key activities:
- Create a Cart service with its own datastore (e.g., Redis or PostgreSQL) for session and cart items.
- Use the API gateway to route cart operations.
- Synchronize with the monolith via events for product and inventory validation.
- Ensure idempotency and session stickiness.
- Gradually migrate cart traffic using feature flags.
Output: an independently deployable Cart service.
11. Extract Order Management and Checkout Orchestration (depends on: 10, 6, 7, 9)
Extract Order Management and Checkout Orchestration. This is the core transactional flow and requires a saga pattern.
Key activities:
- Create an Order service that orchestrates checkout using the saga pattern.
- Integrate with payment providers, inventory, pricing, and customer services.
- Migrate order placement and management APIs.
- Use events for order status updates.
- Ensure distributed transaction consistency and compensation logic.
Output: an independently deployable Order service handling the checkout flow.
12. Extract Pricing and Promotions Service (depends on: 11)
Extract the Pricing and Promotions service. This is the most complex module with 200k lines of rules.
Key activities:
- Analyze and document the existing pricing rules and country-specific logic.
- Implement a new Pricing service, possibly using a rules engine (e.g., Drools).
- Migrate pricing calculations and promotions to the new service.
- Execute after other services are stable and outside peak seasons.
- Use extensive testing and canary releases.
Output: an independently deployable Pricing service with clear rules.
13. Database Decomposition and Stored Procedure Refactoring (depends on: 3)
Decompose the database and refactor stored procedures. This is a cross-cutting concern that runs alongside service extraction.
Key activities:
- Start with logical separation: create schemas per service and move tables gradually.
- Refactor stored procedures into application code or move them to services.
- Eventually, give each service its own database instance.
- Use CDC and dual-write for data consistency during transition.
- Keep the monolith DB as source of truth until cutover.
Output: a decomposed database with clear data ownership.
14. Reorganize Teams for Independent Deployment (depends on: 1, 2)
Reorganize teams for independent deployment. This step enables long-term autonomy.
Key activities:
- Reorganize teams around services (stream-aligned teams).
- Give each team ownership of its service's repository, CI/CD, and on-call.
- Implement an internal developer platform for self-service deployments.
- Establish service level objectives (SLOs) and error budgets.
Output: autonomous teams that can deploy independently.
15. Post-Migration Optimization and Monolith Decommissioning (depends on: 12)
Optimize after migration and decommission the monolith. This step wraps up the migration.
Key activities:
- After each service extraction, remove dead code from the monolith.
- Gradually reduce the monolith to a smaller core (e.g., back-office).
- Plan eventual decommissioning of monolith components.
- Document learnings and update architecture.
Output: a leaner monolith and a fully service-oriented architecture.
Previous Proposal 3 (ID: 14efa153-1aa1-47b0-9435-75fba2e57cfe, Agent: qwen3.8-flash_initial_3 - YOUR OWN previous proposal, LLM: alibaba/qwen3.8-flash):
Estimated Complexity: high
Success Metrics: - **Zero Downtime**: Achieve 100% availability of the e-commerce platform throughout the 12 months, including planned maintenance windows.
- **Deployment Independence**: New services can be deployed independently; no code commit forces a full 30-minute monolith downtime. Time-to-deploy for a new service < 5 minutes.
- **Database Decoupling**: Eliminate cross-service SQL joins. The monolith database write load decreases by 90%.
- **Peak Capacity**: System handles 12x traffic load (approx. 480k orders/day) with < 200ms latency at P95 during load tests.
- **Search Latency**: Product availability reflected in search results within < 30 seconds of inventory update (replacing nightly rebuild).
- **Pricing Stability**: 0% deviation in price calculation results between the new architecture and the legacy 'golden master' characterization tests.
Steps (10):
1. Foundation: Infrastructure, Observability, and Safety Net
Before extracting any service, the team must build the 'operating system' for distributed applications. This step focuses on enabling independent deployment and providing real-time visibility into the legacy monolith. The goal is to create a safety net that makes subsequent refactoring steps low-risk and reversible.
* **CI/CD Pipeline**: Implement a dual-track pipeline. The existing monolith gets a 'speedy' pipeline for hotfixes, while a new pipeline infrastructure is set up (e.g., Kubernetes/ECS) ready for independent service deployment.
* **Observability Suite**: Deploy centralized logging (ELK/Loki), metrics (Prometheus/Grafana), and crucially, **Distributed Tracing** (Jaeger/Zipkin). Even within the monolith, we must map request flows to identify coupling.
* **Service Mesh / API Gateway**: Install an API Gateway (e.g., Kong, Nginx ingress) in front of the monolith. This is the 'strangler fig' entry point. All traffic must flow through here. We will use it to route traffic to new services or fallback to the monolith.
* **Feature Flags**: Integrate a feature management system (e.g., LaunchDarkly, Unleash) to decouple deployment from release. This allows us to deploy code that is inactive and test it behind flags.
2. Domain Analysis and Boundary Definition (Strangler Pattern) (depends on: 1)
You cannot extract a service without knowing the domain. With 2M lines and 'unknown' pricing logic, this step is about mapping the terrain. We aim to identify low-risk, high-cohesion boundaries for the first extractions and mark the 'danger zones' (Pricing) for later.
* **Event Storming**: Run workshops with the five teams to map business flows (e.g., 'Checkout', 'Return') and identify command/event boundaries.
* **Code Hotspot Analysis**: Use static analysis tools (e.g., SonarQube, CodeScene) to find files changed together (logical coupling) and complex methods.
* **Dependency Matrix**: Create a matrix showing which database tables are accessed by which application modules. This is critical for the database refactoring later.
* **Service Extraction Plan**: Finalize the order of extraction. Recommended: **Search/Catalogue** (read-heavy, low transactional consistency risk) or **Inventory** (async, distinct boundary). Avoid 'Pricing' initially due to complexity and 'Checkout' until foundational identity is stable.
3. Data Platform Strategy: Outbox Pattern and CDC (depends on: 2)
The 1.2TB PostgreSQL DB with stored procedures is the 'database of doom' for migration. We must stop using cross-module SQL joins. This step introduces a data change capture layer to allow services to communicate via events rather than DB writes.
* **Database Isolation**: Begin identifying tables exclusive to the chosen first domain (e.g., Catalogue tables). Grant strict read-only access to other modules if possible, or refactor code to remove cross-table joins.
* **Change Data Capture (CDC)**: Deploy a tool (e.g., Debezium or Kafka Connect) to stream PostgreSQL WAL logs to a message broker (Kafka/Pulsar). This creates a stream of data changes that can be consumed by other services.
* **Transaction Outbox**: Refactor the monolith code to use an 'Outbox Pattern' for domain events. Instead of just writing to the DB, it also writes a message to an 'Outbox' table in the same transaction. A relay process moves this to Kafka. This ensures 'at least once' delivery and keeps the monolith's transactional integrity while enabling async communication.
4. Extraction of First Service (The 'Read-Only' Pilot) (depends on: 1, 3)
To learn safely, we extract a 'read-only' service with no transactional complexity. The **Product Catalogue/Search** is the best candidate. It is currently Lucene-based, rebuilt nightly. We will move to real-time indexing to improve product freshness.
* **Build the Catalogue Service**: Create a new microservice that owns the Catalogue database tables. It exposes gRPC/REST endpoints for fetching products.
* **Real-time Sync**: The new service subscribes to the CDC events for product changes (from S3). It updates its internal Lucene/Opensearch index in real-time. This eliminates the nightly rebuild and provides immediate search visibility.
* **Dual Read Path**: The monolith code for 'Search' is modified to check a feature flag. If enabled, it calls the new Catalogue Service; otherwise, it uses the old internal Lucene logic.
* **Shadow Traffic**: Use the API Gateway to duplicate live traffic. Send requests to both the monolith and the new service. Compare the responses. Only when error rates are 0% do we flip the feature flag for production traffic.
5. Extraction of Identity and Customer Accounts (depends on: 4)
Next, we extract the **Customer Account** domain. This serves both the storefront and the mobile app. This is a write-heavy domain, requiring careful transaction handling with the legacy monolith during the transition.
* **Service Implementation**: Implement the 'Customer Service' (JWT generation, profile management, authentication). It owns its own database schema (User, Address).
* **Sync with Legacy**: The service publishes 'UserUpdated' and 'UserCreated' events via Outbox/CDC. The monolith listens to these events to keep its local copy of user data synchronized.
* **Strangler Endpoint**: The API Gateway routes '/api/login', '/api/account' traffic directly to the new service. The monolith stops handling these requests. Front-end applications must be updated to handle the new response format (versioning).
* **Database Decoupling**: Over time, remove read access to the monolith's user table for all other domains, forcing them to use the Identity service.
6. Extraction of Inventory Synchronization (depends on: 5)
Inventory is currently updated every 15 minutes via files. This is a bottleneck. We will extract this into a service that integrates directly with the Warehouse Management System (WMS).
* **Inventory Service**: Build a service that consumes warehouse data feeds (replacing the file drop). It updates a centralized stock level view.
* **Event Publishing**: When stock levels change, publish `StockLevelChanged` events to Kafka.
* **Monolith Integration**: Refactor the Cart/Checkout code in the monolith to listen to these events to maintain a local cached view of inventory or to check stock via an API call rather than a SQL join. This removes the 15-minute latency.
* **Consistency Model**: Since inventory is high-concurrency, design a reservation system (Saga) for this service to prepare for the future extraction of Checkout.
7. The 'Black Box' Strategy for Pricing and Promotions (depends on: 6)
The pricing module (200k lines, unknown rules) cannot be rewritten safely from scratch. We treat it as a 'legacy core'. We will wrap it in a service but keep the internal logic untouched in the monolith initially, or isolate it.
* **Characterization Tests**: Write massive integration tests that record the input/output of the pricing module for all 8 countries and 3 currencies. This creates a 'golden master'.
* **Decouple Dependencies**: Refactor the pricing code to rely only on 'Customer', 'Product', and 'Inventory' data fetched via interfaces, not direct DB calls. This prepares it for extraction.
* **Extract as 'Black Box'**: Wrap the existing pricing logic into a new `Pricing Service`. Move the 200k lines of code into this project. It calls a dedicated read-replica database of the pricing tables. This service does not communicate with others directly but is called by the 'Cart' service.
* **Validation**: Run 'shadow mode' traffic against this new service to ensure it matches the golden master before routing any production traffic.
8. Orchestration Layer: Cart and Checkout (The Saga) (depends on: 7)
Checkout is the highest risk. It requires distributed transaction management. We will implement the Cart as a service and the Checkout process as an orchestrator using Sagas.
* **Cart Service**: Extract cart logic into its own stateless/stateful service (Redis-backed). This decouples the browsing experience from the order processing.
* **Checkout Orchestrator**: Build a new 'Order Service' that does not do the work itself but coordinates the process. When a checkout starts, the Order Service begins a **Saga**.
* **Saga Steps**: 1. Validate Pricing (via Pricing Service), 2. Reserve Inventory (via Inventory Service), 3. Authorize Payment (via Payment Service), 4. Create Order Record. If step 3 fails, step 1/2 must be compensated (rollback).
* **Idempotency**: Ensure all services in the saga accept Idempotency Keys to prevent double-charging or double-stock deduction.
9. Extraction of Payments and Order Management (depends on: 8)
Complete the order lifecycle. Move payment integration and order status tracking out of the monolith.
* **Payment Gateway**: Extract the integration with the 3 providers into a `Payment Service`. This service handles webhooks, refunds, and tokenization (PCI scope reduction).
* **Order Management System (OMS)**: Move the database table `orders` and associated history into a new `Order Service`. It consumes the events generated by the Checkout Saga.
* **Back-office Migration**: The back-office (300 staff) is likely server-rendered. Refactor these screens to consume the new `Order Service` APIs. Remove the back-office's direct SQL access to the orders table. This is crucial for reducing load on the monolith DB.
10. Legacy Cleanup and Peak Season Preparation (depends on: 9)
The monolith should now be a 'hollowed-out' shell (mostly just the legacy pricing rules inside a service or a 'legacy' module). We prepare for the peak sales in Jan/July.
* **Database Downsizing**: Detach the schema ownership. The monolith should ideally only connect to a 'read-only' replica for historical data or a small remnant DB.
* **Performance Tuning**: The new architecture is now the single point of failure. Optimize the message broker (Kafka) and API Gateway for 12x traffic.
* **Chaos Engineering**: Run game-days testing resilience. Kill a service (e.g., Search) and ensure the storefront degrades gracefully (shows empty search results but allows cart access).
* **Final Monolith Decommission**: Identify the remaining monolith code. Delete it. If it's just a 'legacy gateway', replace it with pure API routing. The 'Monolith' label should now refer only to the Pricing Service or similar, not a single deployable unit.
Please, considering the previous proposals as ideas that could be considered, focus on the main objective and generate an IMPROVED proposal or a completely DIFFERENT perspective if you deem it appropriate. Only if you consider any of them is amazing and impossible to improve, answer with the same proposal.
The plan has these parts:
- "steps": the list of steps, each with "step_id" (a short label unique within this proposal, such as S1, S2, S3), "title" (a short, descriptive title), "description" (what the step does and how, in Markdown: a short opening paragraph and then, if there are several concrete things to say, a bullet list) and "dependencies" (the step_ids of the other steps of THIS proposal that must be completed first; empty if none).
- "estimated_complexity": "low", "medium" or "high".
- "success_metrics": clear and measurable success metrics, one per line as a bullet list.
Think deeply about the problem, considering all aspects and implications. Develop a comprehensive understanding of what needs to be done to achieve the objective, then produce the plan.
{"steps": [{"step_id": "S1", "title": "Mobilization and Strategic Freeze Planning", "description": "Establish the governance and safety constraints for the migration. This step defines the 'no-touch' windows around peak seasons (January and July) and sets up the steering committee to manage the complexity of a 2M LOC codebase.\n\n- **Team Alignment**: Reorganize the 5 teams into 'Service-First' pods. Each pod owns a target service extraction alongside their monolith maintenance duties.\n- **Risk Framework**: Define strict 'Freeze Windows' (e.g., Dec 15–Jan 15, June 15–July 15) where no architectural changes are permitted, only bug fixes.\n- **Dependency Mapping**: Create a 'Coupling Heatmap' identifying the most entangled modules (likely Pricing and Checkout) to isolate them for later phases.", "dependencies": []}, {"step_id": "S2", "title": "Target Architecture and Domain Boundaries", "description": "Perform rigorous Domain-Driven Design (DDD) to define service boundaries. Given the 2M LOC and 350 tables, abstracting the domain is critical to prevent 'distributed monolith' outcomes.\n\n- **Strategic DDD**: Map current modules to bounded contexts (Catalogue, Pricing, Orders, Identity, Fulfillment).\n- **Database Decomposition Design**: Define the target data model for each service. Explicitly list which of the 350 tables move to which service and which cross-module joins must be replaced by API calls or events.\n- **Contract Definition**: Draft API contracts (OpenAPI/GraphQL) for the core services to ensure backward compatibility with the existing frontend.", "dependencies": ["S1"]}, {"step_id": "S3", "title": "Core Infrastructure and Observability Foundation", "description": "Build the 'platform' that allows services to exist independently. You cannot safely extract services without first having the tools to see, test, and deploy them individually.\n\n- **Kubernetes Cluster**: Provision a production-grade K8s environment with strict namespace isolation.\n- **API Gateway**: Deploy a robust API Gateway (e.g., Kong, AWS ALB) to sit in front of the monolith. This is the 'Traffic Switcher' for the Strangler Fig pattern.\n- **Observability Stack**: Implement Distributed Tracing (Jaeger), Centralized Logging (ELK/Loki), and Metrics (Prometheus). You must be able to trace a request from the gateway through a new service and back to the monolith.\n- **CI/CD Pipelines**: Create independent deployment pipelines for services, allowing 15-minute rollback capabilities distinct from the monolith's 2-week cycle.", "dependencies": ["S1"]}, {"step_id": "S4", "title": "Test Harness: 'Golden Master' Characterization", "description": "Since testing the new logic against the old logic is the primary validation method, create an automated regression suite that captures the 'current truth' of the legacy system.\n\n- **Input Logging**: Configure the monolith to log all incoming requests (and their responses) to a secure data lake, anonymizing PII.\n\n- **Replay Engine**: Build a tool that takes a captured legacy request, sends it to both the legacy monolith and the new service, and diffs the responses.\n- **Coverage Baseline**: Establish a 100% test coverage requirement for the *interfaces* being extracted. If you extract 'Search', you must have a test for every possible search query variant currently supported.", "dependencies": ["S3"]}, {"step_id": "S5", "title": "Extraction 1: Catalogue and Read-Only Search", "description": "The 'Low Hanging Fruit'. Extract the read-only Catalogue and Search capabilities first. This builds confidence and proves the Strangler Fig pattern without touching transactional data.\n\n- **New Service**: Build 'Catalogue Service' that reads from a replicated Postgres (via logical replication) or a dedicated search DB (Elasticsearch).\n- **Traffic Shift**: Configure the API Gateway to route `/products` and `/search` requests to the new service.\n- **Fallback**: If the service fails, the gateway should immediately reroute to the legacy monolith (circuit breaker).\n- **Optimization**: Replace the nightly Lucene rebuild with real-time indexing to instantly reflect price/inventory changes.", "dependencies": ["S4"]}, {"step_id": "S6", "title": "Extraction 2: Customer Identity and Profile", "description": "Extract user data handling. This decouples the 'who' from the 'what' (purchases), allowing independent authentication scaling.\n\n- **Account Service**: Move user tables (Login, Profile, Address) to a dedicated service.\n- **Session Migration**: Implement a token-passing strategy where the legacy monolith trusts tokens generated by the new Identity Service.\n- **Read-Through Cache**: The legacy monolith should stop querying the user table directly; instead, it fetches user details from the Identity Service via an internal REST call or cached event.\n- **Rollback**: Keep a 'sync-back' script to ensure if users are created in the new service, the legacy DB knows about them during the transition period.", "dependencies": ["S5"]}, {"step_id": "S7", "title": "Database Decoupling: The 'Anti-Corruption' Layer", "description": "The most dangerous step. Breaking the 1.2TB DB entanglement requires intercepting the stored procedures. We stop writing to the shared DB from new services.\n\n- **CDC Implementation**: Deploy Debezium to capture Postgres Write-Ahead Logs (WAL) into Kafka. This allows new services to be notified when the monolith updates data.\n- **Outbox Pattern**: Refactor the monolith code so that when it writes to the DB, it also writes a 'domain event' to an internal Outbox table, which Debezium then publishes.\n- **Read-Only Replicas**: Force new services to read from read-only replicas of the legacy DB to prevent them from causing lock contention on the master.", "dependencies": ["S3", "S5"]}, {"step_id": "S8", "title": "Extraction 3: Inventory and Fulfillment Interface", "description": "Move the inventory logic out. This separates the 'Stock' truth from the 'Order' truth, preparing for the complex checkout.\n\n- **Inventory Service**: Create a service to hold the 'Single Source of Truth' for current stock levels.\n- **Legacy Integration**: The monolith's checkout flow must now ask the Inventory Service to 'Reserve Stock' before processing payment.\n- **Warehouse Sync**: Move the 15-minute file exchange logic into this service, isolating the legacy code from warehouse connectivity issues.\n- **Concurrency Handling**: Implement optimistic locking in this service to handle high-concurrency 'reserve' requests during sales.", "dependencies": ["S7"]}, {"step_id": "S9", "title": "Extraction 4: Pricing and Promotions (The 'Black Box')", "description": "Extract the 200,000 LOC pricing engine. Do not rewrite the logic yet; wrap it. This is a 'Strangler Fig' step, not a refactoring step.\n\n- **Encapsulation**: Move the existing pricing code (and its dependencies) into a new Spring Boot project called 'Pricing Service'.\n- **Dependency Injection**: Replace direct DB access within the pricing logic with interfaces that call the Catalogue and Customer services via API.\n- **Performance Parity**: Ensure the latency added by moving pricing to a separate network call is negligible (<50ms). Cache aggressively at the service level.\n- **Validation**: Use the Golden Master (S4) to replay all historical orders and verify the new service returns the exact same price down to the cent.", "dependencies": ["S8"]}, {"step_id": "S10", "title": "Extraction 5: Checkout Orchestrator (Saga Pattern)", "description": "Replace the monolithic transaction with a distributed saga. This is the final piece of the transactional flow.\n\n- **Orchestrator**: Build a lightweight service that coordinates the 'Checkout' process.\n- **Saga Logic**: When an order is placed: 1. Call Pricing Service. 2. Call Inventory Service (Reserve). 3. Call Payment Gateway (External). 4. Call Order Service (Create).\n- **Compensation**: If step 4 fails, the Orchestrator triggers 'Cancel Reserve' on the Inventory Service and 'Void' on the Payment Gateway.\n- **Legacy Cutoff**: The monolith's 'Checkout' screen is replaced by a frontend form that calls this Orchestrator API.", "dependencies": ["S9"]}, {"step_id": "S11", "title": "Final Monolith Decomposition and Clean-up", "description": "At this stage, the monolith is hollowed out, containing mostly code that is called by the new services or legacy admin functions.\n\n- **Admin Panel**: Move back-office functionality (Order management, Refunds) into a 'Management Service' that reads from the new event streams.\n- **Code Deletion**: Delete the code for the extracted domains (Pricing, Search, Cart) from the monolith repository to enforce boundaries.\n- **Database Cleanup**: Drop the tables owned by new services from the legacy monolith database.\n- **Performance Tuning**: Optimize the remaining monolith for the only things it does: serving legacy redirects and perhaps a few 'orphaned' modules.", "dependencies": ["S10"]}, {"step_id": "S12", "title": "Peak Season Stress Test and Handover", "description": "Prepare for the high-volume events in Jan/July. Validate the new architecture holds under pressure.\n\n- **Chaos Engineering**: Randomly kill the Search or Inventory services and verify the site degrades gracefully (e.g., 'Search temporarily unavailable') without crashing the checkout.\n- **Load Testing**: Simulate 12x peak traffic using tools like Gatling/JMeter against the new APIs.\n- **Runbooks**: Finalize operational playbooks for every team. Who owns what? How to restart a dead service? How to fallback to the monolith if the database fails?", "dependencies": ["S11"]}], "estimated_complexity": "high", "success_metrics": "- **Zero Downtime**: 100% availability maintained throughout the 12-month migration, excluding planned maintenance windows.\n- **Rollback Speed**: Every service deployment is reversible in < 10 minutes via automated traffic switching at the Gateway.\n- **Peak Performance**: The new architecture sustains 12x baseline load (480k orders/day) with < 200ms P95 latency for Checkout.\n- **Data Integrity**: Zero discrepancies between pricing calculations of the old monolith and the new Pricing Service across 1 million replayed requests.\n- **Independence**: Teams successfully deploy their services on a weekly cadence without coordinating with the monolith's bi-weekly release."}Round 2 — refinement 2 of 2
The agents converged on a calendar-first approach with explicit peak-season freezes and seam-level verification. They abandoned unrealistic blanket test coverage goals in favor of golden-master characterization and four-stage cutover playbooks.
The calls of this round
Influences: who took what from whom
| Round 2 ↓ · round 1 → | Proposal 1 | Proposal 2 | Proposal 3 | New steps |
|---|---|---|---|---|
| Proposal 1 |
kept4 | same titles7 analyst sees+1 / −0 | same titles1 analyst sees+1 / −1 | new8 |
| Proposal 2 |
same titles0 analyst sees+1 / −0 | kept15 | same titles0 analyst sees+1 / −1 | new3 |
| Proposal 3 |
same titles5 analyst sees+1 / −0 | same titles1 analyst sees+1 / −1 | kept4 | new6 |
It abandoned its unrealistic 70% monolith coverage goal. It adopted the calendar-first, scope-ladder, and four-stage cutover playbook from Proposal 2. It also parallelized the pricing rules cataloging to avoid false dependencies.
- Abandoned blanket 70% coverage in favor of seam-level golden master verification.
- Adopted explicit freeze windows and a scope ladder to protect peak seasons.
- Parallelized pricing characterization with data platform work to shorten the critical path.
- The 20-step sequence remains highly granular, risking rigid execution over adaptive delivery.
- Some steps still imply sequential dependencies that could be parallelized further.
- Proposal 2 : Calendar-first charter, scope ladder, table ownership enforcement, seam-level verification, and the four-stage cutover playbook.
- Proposal 3 : The replay engine concept for the golden master.
- Proposal 3 : Implementing the checkout orchestrator before the payment service.
+ Program Setup, Scope Ladder, Organizational Model, and Peak-Safe Calendar+ Pricing Module: Rules Catalog and Golden-Master Characterization (Parallel with Data Platform)+ Extract Returns: Low-Stakes Proof of Four-Stage Playbook+ Extract Inventory: Warehouse Sync Improvement and Reservation Semantics+ Extract Cart: Stateful Session Service+ Extract Pricing as Black Box Using Golden-Master Validation+ Extract Payment: PCI-Strict Regime and Provider-by-Provider Cutover+ Extract Orders: Event-Sourced Record of Truth+ Extract Checkout: Distributed Saga Orchestration (Highest Risk)+ Chaos Engineering, Resilience Testing, and Pre-Peak Validation+ Monolith Decommissioning and Steady-State Operations+ Peak Season Validation and Post-Peak StabilizationProgram setup, peak-aware calendar, rollback charter and scope ladderSplit the deployment unit and retire the 30-minute maintenance windowExtract Returns as the first write-path and own-database proofExtract Inventory and replace the 15-minute warehouse file exchangeExtract CartExtract Pricing and Promotions as an unchanged black boxExtract Payment under a stricter regime than anything elseExtract Order Management with an explicit state machineCompose Checkout from independent services using a sagaDecommission the monolith core and harden for the second peak
The plan produced
1. Program Setup, Scope Ladder, Organizational Model, and Peak-Safe Calendar new
Establishes the governance framework and constraints that all later work obeys. The calendar is the binding constraint—January and July peaks must not be put at risk—so it is decided first, before any technical choices.
Inception and Baselines: Run a two-week inception to establish current state: build time, deployment lead time, change failure rate, MTTR per team, module-change frequency, database load profiles (all measurable, not asserted).
Calendar and Freeze Windows: Declare hard freezes from December 1–January 15 and June 1–July 15; only rollback-enabling and hardening changes allowed during freezes. Confirm two open delivery windows per year (February–May and August–November); all migration work must fit these windows. No change on checkout path lands within four weeks of a freeze.
Scope Ladder: Define ranked rungs 1–6 that deliver the core objective; rungs 7+ are optional. Slippage means stopping at a rung boundary, never mid-increment. Rungs: 1. Platform ready. 2. Search extracted and proven. 3. Returns and Inventory proven at low stakes. 4. Payment and Orders stable. 5. Checkout orchestration live and soaking. 6. Back-office migrated, monolith core reduced.
Organizational Model: Define service-aligned teams (Search, Orders, Inventory, Payments, Customer, Fulfillment) with clear ownership, on-call rotations, and SLOs per service. Each team owns codebase, pipeline, database schema, and incidents by month 6. Transition plan: teams split duties (monolith maintenance + service) until month 3, then shift to service-primary by month 6.
Rollback Charter: Every increment ships an expand/contract database change, a feature-flag kill switch, and a recorded game-day rehearsal. No go-live without tested rollback in < 30 minutes.
Peak-Readiness Gate: Define gate to run six weeks before each peak (mid-November, mid-May): 12x load test, capacity headroom check, rollback rehearsal, error-budget review. Gate is pass/fail; failed gate defers work to next window.
Capacity Budget: Allocate 40–50% of five teams' capacity for migration; staff scope ladder to fit capacity, not to fill the year. Create migration enablement squad of six rotating engineers to own platform, shared cuts, and risky data work.
2. Executable Architecture Map, Table Ownership, and Boundary Enforcement (after 1) from P2 step 2
Produces an architecture map that the build itself enforces. Five teams in one repo will silently re-couple anything separated if not policed, so enforcement is embedded in the map.
Real Coupling via Tracing: Instrument monolith with distributed tracing; let it run four weeks to capture real call paths—static imports miss true coupling.
Table Ownership Matrix: Parse every SQL statement, ORM mapping, and stored procedure; cross-check against database query logs. Build table-to-module and query-to-module map. Assign every 350 table to exactly one owning module; tables nobody can own are 'contested' and scheduled into data work (Step 7).
Scoring and Extraction Sequence: Score each candidate service on coupling, transactional risk, change frequency, and peak-path criticality. This ranking (not intuition) drives extraction order.
Enforcement via Automation: Add ArchUnit rules to CI to fail builds on new cross-module Java dependencies (existing violations frozen in baseline that may only shrink). Add SQL linter to CI to fail on cross-module joins and cross-module writes (same shrinking baseline). Violations tracked weekly in architecture review.
Stored Procedure Audit: Inventory all stored procedures; attribute to owning module; plan move into module code or leave as module-private function. No stored procedure may touch two modules' tables post-extraction.
Architecture Decision Records: Publish target service list, owning team per service, and reasoning as ADRs.
Mid-Program Review: Hold review at month 6 to re-rank scope ladder using what the map actually revealed. This is the one planned re-planning point of the program.
3. Delivery Platform: Per-Service Pipelines, Gateway, Feature Flags, and Environments (after 1, 2) from P2 step 3
Builds the delivery and traffic machinery that makes every later step reversible. No service is extracted until its team can deploy, flag, and route independently.
Kubernetes and Namespaces: Extend platform on Kubernetes (or existing container platform) with one namespace per service, quotas, and autoscaling sized for 12x peak (480k orders/day). Establish dev/staging/prod with strict resource isolation.
API Gateway: Deploy API gateway (Kong, AWS ALB) in front of monolith as strangler entry point. Storefront, mobile app, and back-office traffic flow through gateway from day one, even while routing everything to monolith. Gateway enforces rate limiting, bulkheads, timeouts, and circuit breakers.
Feature-Flag Service: Deploy centralized feature-flag system (LaunchDarkly, Unleash). Require every new call path to be flag-guarded. Flags are the primary rollback instrument; changes to traffic routing require no code deployment.
Per-Module CI/CD Pipeline: Give every module its own independent CI/CD pipeline and environment. Monolith keeps current pipeline for hotfixes until Step 5 replaces it. Pipeline includes automated security scanning, performance baselines, and contract-test gates.
Secrets and Configuration: Introduce secrets management (Vault) and per-environment configuration. Behavioral changes require no monolith redeploy.
Golden-Path Templates: Define reusable templates for new services: build layout, Dockerfile, pipeline stages, observability instrumentation, health checks, feature-flag integration, database migration tool. Extraction starts from template, not blank page.
Permanent Environments: Reserve two full-size environments: (1) production-like soak environment for multi-week stability validation, (2) load-test environment capable of 12x traffic generation against production-shaped data (8 countries, 3 currencies, 4 languages, realistic product catalog).
4. Observability, Business SLOs, Error Budgets, and Automated Rollback Controller (after 3) from P2 step 4
Makes the system observable so canaries are judged automatically and reverted without human guessing. This is the prerequisite for rollback promises in all later steps.
Observability Foundation: Deploy centralized logging (ELK/Loki), metrics (Prometheus/Grafana), and distributed tracing (Jaeger) with trace correlation working across gateway, monolith, and every new service from day one.
Blind-Spot Instrumentation: Instrument monolith's unmeasured aspects: query latency by module, connection-pool saturation, Lucene rebuild duration, warehouse file-exchange lag, stored procedure execution time, lock contention.
Business SLOs: Define SLOs on business outcomes, not infrastructure:
- Checkout success rate ≥ 99.5%
- Order confirmation latency p99 ≤ 5 seconds at baseline (40k orders/day) and peak (480k orders/day)
- Search result latency p95 ≤ 1 second
- Payment authorization latency ≤ 2 seconds
- Price computation latency ≤ 200 ms
- Warehouse sync freshness ≤ 2 minutes end-to-end (vs. current 15 minutes)
- Cross-module data consistency: hourly reconciliation shows < 0.001% row-count discrepancy
Error Budget and Rollback Policy: Attach error budget to each SLO. When a service burns budget (or latency diverges > threshold during canary), its rollout stops automatically and flags revert without negotiation. Document policy explicitly; use during peaks without exception.
Automated Rollback Controller: Build system that monitors error rate and latency divergence during canary. On breach, gateway shifts traffic back and flags disable automatically. Fallback requires no human intervention. Test this automation in monthly game days.
Dashboards: Create per-service dashboards readable by tired engineers at 3 AM (traffic, errors, latency p50/p95/p99, database load). Create program dashboard showing progress against scope ladder, rung by rung.
5. Pricing Module: Rules Catalog and Golden-Master Characterization (Parallel with Data Platform) (after 1, 2) new
Catalog the 200k LOC pricing engine behavior before any extraction attempt. This is the foundational risk mitigation for the most complex module; it runs in parallel with data platform work (Step 7) because it is independent of infrastructure.
Rules Discovery and Documentation: Analyze and document all pricing rules in scope: country-specific logic (8 countries), currency handling (3 currencies), promotional rules, seasonal pricing, bulk discounts, loyalty point applications, regional variations. Create a living rules inventory.
Historical Request Corpus: Capture at least 1 million real historical pricing requests from production logs, covering all 8 countries, 3 currencies, 4 languages, all promotion types discoverable, edge cases, peak-season variations. Record exact inputs and outputs.
Golden-Master Characterization Suite: Build automated harness to replay corpus against monolith, capturing deterministic responses. This suite is the 'golden master': any new pricing service must match 100% of outputs. Suite becomes the automated gate for pricing extraction (Step 14).
Test Data Expansion: Supplement historical data with synthetic edge cases: multi-currency conversions, minimum purchase thresholds, conflicting promotions, time-based seasonal rules, inventory-driven pricing, customer-segment overrides.
Dependency Mapping: Explicitly document which customer attributes, product attributes, inventory levels, time-based factors, and external parameters affect pricing. Identify all cross-module dependencies that pricing currently reads from monolith (e.g., customer loyalty status from Customer module, product hierarchy from Catalogue module).
Baseline Validation: Run golden master against monolith to establish baseline passing rate. Document any non-deterministic behavior or race conditions found. This baseline is locked; no drift allowed during migration.
CI Gate Definition: Define hard rule: pricing service extraction cannot proceed until characterization tests pass 100% against both monolith and new service. Any divergence blocks ramp. This gate is not negotiable.
6. Seam-Level Verification: Golden Master, Contracts, Shadow Diffing, and Reconciliation (after 2, 3) from P2 step 6
Replaces impossible goal of blanket test coverage with verification exactly at the cut point. A 2M-line monolith cannot reach 70% coverage in a year; a service boundary can be verified to very high standard in weeks.
Characterization Harness for All Services: Build framework to record real production requests (anonymizing PII) and replay against monolith. Capture full responses as golden master. Every extracted service must pass golden master on its public API before taking live traffic. Output a diff report, not pass/fail.
Consumer-Driven Contracts (Pact): Require contracts between monolith and each new service, and between services themselves. A change on one side breaks a build instead of waiting for production. Contracts versioned; breaking changes trigger explicit communication plan.
Shadow Traffic and Response Diffing: Mirror live requests to new service; compare responses field by field (not just status codes). Measure divergence rate continuously. Gate traffic ramp on divergence < 0.01% for 48 hours.
Per-Module Data Reconciliation: Build data reconciliation as first-class test, not afterthought. Compare row counts, checksums, and business invariants on hourly schedule. Owner assigned; alert threshold set. Reconciliation runs continuously during transition period (Stages A–C of cutover playbook).
Synthetic Canary Transactions: Implement real checkout, return, and search transactions executing every few minutes. Alert on functional regression before customers notice. Include multi-country, multi-currency variations.
Explicit Non-Goal: Do not pursue blanket line coverage of monolith. Track coverage only for newly written service code, target 80%. Seam-level verification replaces this impossible goal.
7. Data Platform: Schema Ownership, Join Elimination, CDC, Transactional Outbox, and Four-Stage Cutover Playbook (after 2, 3) from P2 step 7
The hardest and most under-specified part of most migrations. This work is independent of service extraction, so it starts in month 1 and runs in parallel. It is the foundation for reversible data transitions.
Database-Enforced Ownership: Assign every PostgreSQL table to exactly one module. Create one role per module, able to write only its own schema and to read others only through defined views. Database rejects cross-schema writes at the engine level, not by convention. Test this enforcement in CI.
Stored Procedure Refactoring: Inventory every stored procedure, attribute it to owning module. Either move logic into that module's application code or leave as module-private database function. After extraction, no stored procedure may touch two modules' tables.
Cross-Module Join Elimination: Eliminate cross-module joins one at a time, replacing each with an API call (preferred during cutover), an event-fed materialized read model, or a duplicated read-only projection. Track count per module; drive to zero before that module is extracted.
Change Data Capture (CDC): Deploy Debezium reading PostgreSQL WAL into Kafka. This publishes monolith domain events with zero application change—lowest-risk start possible. Configure per-table CDC; test at peak load (480k events/day during 12x peak).
Transactional Outbox Pattern: For all new services, add outbox table. When service writes business state, it writes domain event atomically in same transaction. Outbox relay publishes to Kafka, ensuring no event loss. Implement poison-pill handling for failed publishes.
Four-Stage Cutover Playbook (Reusable): Define one playbook applied identically every service extraction:
- Stage A (Shadow-Read): Service owns schema logically, reads from CDC into its own store, serves shadow traffic only. Monolith remains system of record; no cutover yet.
- Stage B (Read Cutover): Reads cut over to new service via flag. Monolith stays system of record via reverse-CDC replication. Rollback is flag flip + reconciliation pass.
- Stage C (Write Cutover): Writes cut over to new service. Monolith tables become read-only replicas fed by reverse CDC from service. Rollback is configuration change (flip sync direction) + reconciliation, not data restore.
- Stage D (Deletion): Old tables and dead code dropped only after module has survived one full peak (January or July) or four clean weeks, whichever is longer. Maintain 90-day read-only archive of old tables for regulatory retention and emergency queries.
Reconciliation Service: Build now (not later) so every cutover has objective consistency check. Compare row counts, business-invariant checksums, monetary totals hourly. Owner assigned; thresholds set. Mismatch is immediate rollback signal.
Storage Migration Timeline: New services start on existing cluster with own schemas. Physical database split (move to separate cluster) happens only once module is stable and proven at peak. This removes a critical-path blocker and allows parallelization.
8. Extract Catalogue and Search: Read-Heavy Pilot Service (after 5, 6, 7)
First extraction, chosen because it is read-heavy, isolated, and carries no transactional risk. It also pays for itself: replacing nightly Lucene rebuild with real-time indexing is a visible business win that buys political cover for harder cuts.
New Catalogue Service: Create service owning product, category, media, and attributes tables. Build search API using Elasticsearch/OpenSearch with real-time indexing.
CDC Feed: Subscribe to CDC stream from monolith. ProductUpdated, PriceChanged, InventoryUpdated events trigger real-time search index refresh. Product availability reflects in search within < 60 seconds of change (vs. nightly rebuild).
Shadow Traffic and Diff Validation: Route requests through gateway behind feature flag. Run shadow mode: send requests to both monolith Lucene and new Search service; compare result sets field by field. Measure divergence; require < 0.01% for 48 hours before traffic ramp.
Gradual Traffic Ramp: 1% → 5% → 25% → 50% → 100% using feature flags and canary deployments. Rollback controller monitors latency and error rates; reverts flag if breach. Keep old Lucene index warm for two weeks post-cutover as rollback target.
Mobile App Verification: Verify mobile app behavior explicitly; it hits same endpoints. Test session persistence, offline search cache behavior, and app version compatibility during ramp.
Four-Stage Playbook: Execute Stages A–D as defined in Step 7. Stage A (shadow) lasts 1 week minimum. Stage B (read cutover) lasts 2 weeks. Stage C does not apply (reads only). Stage D (cleanup) after one peak or four weeks.
Soak Period: Land this extraction in open delivery window; soak at least four weeks before freeze (Dec 1 or June 1). No extraction reaches production less than four weeks before a freeze.
9. Extract Returns: Low-Stakes Proof of Four-Stage Playbook (after 5, 6, 7) new
Second extraction and first write-path proof. Returns is chosen because it is off peak-critical path, has modest coupling, and exercises full four-stage playbook at low risk. Primary output is a proven, reusable procedure, not just one service.
Returns Service: Build with own schema. Consume order and customer events rather than joining their tables. Implement return state machine: Requested → Approved → Shipped → Received → Refunded.
Full Four-Stage Execution: Apply Stages A–D end-to-end with explicit recorded game day validating each stage rollback path. Stage A (shadow reads) for 1 week. Stage B (read cutover) for 2 weeks. Stage C (write cutover) with reverse CDC. Stage D (cleanup) after one peak or four weeks.
Rollback Rehearsal: Before write cutover, execute full game day: simulate service failure mid-cutover, trigger rollback (reverse CDC, flag flip, reconciliation), verify all data consistent, re-run golden master, confirm back-office queries still work. Record this session; play back monthly.
Back-Office Screens: Keep back-office returns screens on monolith for now (staff workflow untouched). Returns service is API-only; back-office integration comes later (Step 18).
Friction Point Capture: Record every operational friction, process gap, and test hole discovered during extraction. Update playbook from learnings. This step is as much about process validation as about extracting Returns.
Soak and Timing: Execute in open window; soak returns service for minimum four weeks before any freeze. Gate to proceeding to Inventory (Step 10) is successful four-week soak with zero rollbacks and full reconciliation agreement.
10. Extract Inventory: Warehouse Sync Improvement and Reservation Semantics (after 5, 6, 7) new
Removes one of sharpest coupling points (15-minute file-exchange lag) and unblocks checkout work. Inventory runs in parallel with returns because it couples monolith to external warehouse system, not to other modules.
Inventory Service: Ingest warehouse feed directly (SFTP/API) instead of monolith polling. Design reservation semantics now: Reserve (place hold), Confirm (finalize after order), Release (cancel reservation on timeout/failure), with explicit timeout windows. Own stock levels and reservations per product per location.
Parallel Feeds During Transition: Run new ingest in parallel with legacy 15-minute feed. Reconcile hourly until both agree. This validates the new ingest does not miss updates or duplicate changes.
Monolith Inventory Tables as Projection: Keep monolith's inventory tables as read-only replicas fed by CDC from new service during Stage C (write cutover). Cart and checkout continue calling monolith queries unchanged during cutover; no checkout changes yet.
Four-Stage Execution: Apply Stages A–D. Stage A (shadow ingests and reads) for 2 weeks (must survive two 15-minute sync windows and validate no drift). Stage B (read cutover) for 2 weeks. Stage C (write cutover) with reverse CDC. Stage D (cleanup) after one peak.
Peak-Load Testing: Load-test inventory ingest at 12x (400k SKU updates/day during peak). Warehouse feed schedule and sales peaks do not always align; test worst-case concurrency. Validate no reservation deadlocks, no stock over-sells.
Cutover Order: Inventory read cutover must complete before Cart extraction (Step 13) to avoid monolith checkout calling new Inventory service via internal API during transition.
Soak and Gate: Soak minimum four weeks before freeze. Gate to proceeding to Customer (Step 11) is four-week soak with zero reconciliation mismatches and warehouse feed lag improved to < 2 minutes.
11. Extract Customer Accounts and Loyalty: Conservative Authentication Strategy (after 9, 10) from P2 step 11
Extracts customer identity, profile, and loyalty programs. Authentication is deliberately placed late and guarded hardest because auth failures derail e-commerce migrations most often.
Customer Service: Own profile, address, and loyalty tables. Implement country-specific loyalty rules (8 countries, different point accrual rates) as data-driven rules where possible, code where not. Design API: GetCustomer, UpdateProfile, GetLoyaltyBalance, RedeemPoints, AccruePoints.
Authentication Strategy Phase 1: Keep authentication (login) in monolith for now. Customer service exposes only data APIs; token issuance remains monolith's responsibility. This delays risky auth cutover; less risk to peak season.
Distributed Session Handling: Introduce Redis-backed distributed sessions. Services can verify customer identity without querying monolith database. Implement token-validation API so services can verify bearer tokens without round-tripping to monolith.
Data Cutover: Execute four-stage playbook. Stage A (shadow reads) for 1 week. Stage B (read cutover) for 2 weeks. Stage C (write cutover) for new customers, address updates, loyalty accrual. Stage D (cleanup) after one peak.
Golden Master for All Countries: Golden master captures customer queries across all 8 countries, all 4 languages, and all loyalty-rule variations. Shadow-traffic diff must show < 0.01% divergence before read cutover.
Mobile App Session Behavior: Test mobile app's long-lived sessions explicitly; storefront does not hold sessions same way. Validate token refresh, session timeout, and app version compatibility during cutover.
Loyalty Accrual Last: Move loyalty point accrual and redemption last within this step (Stage C final substep). Loyalty error is customer-visible financial error, not technical incident; guard hardest.
Soak and Gate: Soak minimum four weeks. Gate to proceeding to Cart (Step 13) is successful loyalty accrual cutover with zero customer complaints and full reconciliation agreement.
12. Extract Cart: Stateful Session Service (after 6, 7, 10, 11)
Extract shopping cart, which is stateful and sits directly in front of checkout. Extracted before Pricing and Checkout because both depend on stable Cart boundary.
Cart Service on Redis: Build on Redis (or PostgreSQL with session affinity) for session and line-item state. Validate products and inventory through service API calls rather than direct database joins. Design API: AddItem, RemoveItem, UpdateQuantity, GetCart, ApplyCoupon, ClearCart.
Idempotent Operations: Every cart operation is idempotent. Retried add during peak does not duplicate line item. Retried remove is safe. Implement via unique constraint on (session, sku) or idempotency-key header.
Monolith Cart Tables as Projection: Keep monolith's cart tables as read-only projections fed by CDC from Cart service. Back-office screens continue reading old cart tables for abandoned-cart analytics (not yet migrated to service APIs in this step).
Four-Stage Execution: Apply Stages A–D. Stage A (shadow reads) for 1 week. Stage B (read cutover) for 2 weeks (use feature flag; gradual ramp 10% → 50% → 100%). Stage C (write cutover to service); Stage D after one peak.
Business Metric Monitoring: Cart latency surfaces as lost revenue (abandonment), not just error logs. Track cart abandonment rate and add-to-cart latency as primary success metrics during ramp.
Anonymous vs. Authenticated Carts: Test both paths separately; they follow different session-tracking mechanisms and fail in different ways. Ensure cart persists across login boundary.
Soak Before Freeze: Land in open window; soak minimum four weeks before freeze (Dec 1 or June 1). Gate to proceeding to Pricing (Step 14) is four-week soak with cart abandonment rate unchanged or improved and zero lost transactions.
13. Extract Pricing as Black Box Using Golden-Master Validation (after 5, 6, 7)
Extract 200k LOC pricing logic as-is without rewriting. Rules are not understood by anyone, so wrap and characterize rather than refactor. Rule decomposition deferred to follow-up program in writing.
Wrap Without Refactor: Move pricing code into dedicated service, unchanged. Service owns pricing tables post-cutover. Expose single decision API: ComputePrice(customerId, productId, locationId, timestamp, quantityId, loyaltyStatus) → {price, applicablePromotions, taxes, currency}.
Dependency Injection for Reads: Refactor pricing's dependencies so it obtains customer data via Customer service API, product data via Catalogue service API, inventory via Inventory service API. No direct cross-module database joins.
Golden-Master Validation: Run characterization test suite (built in Step 5) against new service. Require 100% output match on all 1M historical requests across all 8 countries, 3 currencies, 4 languages, all promotion types, edge cases. Any divergence blocks ramp; no exceptions.
Shadow Mode Duration: Run shadow traffic against live pricing requests for minimum four weeks, comparing every computed price with monolith. Measure divergence continuously. Divergence > 0.001% blocks ramp.
Gradual Cutover by Country: Cut over per-country rather than all-at-once. Start with lowest-revenue country, validate four weeks per country, then ramp to others. Per-country flags allow independent rollback.
Rollback Path: Keep monolith's pricing evaluator available and warm as rollback target for at least one full peak (January or July) after cutover. Maintain ability to flip back to monolith pricing via feature flag without data restore.
Four-Stage Playbook: Stages A–D applied to pricing tables. Stage A (shadow) 4+ weeks. Stage B (read cutover) 2 weeks per country. Stage C (write cutover) per country. Stage D (cleanup) after one full peak.
Deferred Refactoring in Writing: Publish decision that pricing rule decomposition, DSL, and optimization are explicitly deferred to follow-up program after this migration stabilizes. Include this in all project communications and retrospectives.
14. Extract Payment: PCI-Strict Regime and Provider-by-Provider Cutover (after 5, 6, 7) new
Extract payment processing with stricter regime than any other service. Mistakes are irreversible and regulatory. Extracted before checkout orchestration because checkout cannot be decomposed without payment boundary.
Payment Service: Own integration with three payment providers (tokenization, authorization, capture, refund, provider webhooks). Design API: AuthorizePayment(idempotencyKey, amount, currency, cardToken, customerId) → {authorizationId, status}; CapturePayment(authorizationId); RefundPayment(captureId); HandleWebhook(webhookPayload).
PCI Scope Reduction: No raw card data at rest in service. Card data flows directly from client to provider (tokenization); only tokens stored in Payment service. Credentials in secrets management (Vault). No card data in logs or distributed traces.
Idempotent Operations: Explicit idempotency-key handling. Every payment request is idempotent; retries at peak are normal and must not double-charge. Implement via idempotency-key deduplication store (Redis with TTL).
Provider-by-Provider Cutover: Cut over one provider at a time (start with lowest-volume provider). Stage A (shadow) 2 weeks per provider. Stage B (read cutover, not applicable). Stage C (write cutover) for each provider, maintain fallback to monolith for other providers. Test each provider's decline, timeout, 3-D Secure, and chargeback scenarios explicitly.
Golden Master Scenarios: Golden master covers all three providers, all decline reasons, timeouts, partial authorizations, refund scenarios, chargebacks. Shadow traffic compares full payment outcomes (authId, status, amount, timestamp) before any live provider cutover.
Fraud Detection and 3-D Secure: These paths are usually least-tested and most visible when broken. Test explicitly; goldne master includes fraud-decline and 3-D Secure flows. Verify fraud rules and thresholds carry over unchanged.
Fallback Orchestration: Monolith retains ability to handle payment directly (as fallback) until second peak after Payment service cutover. Checkout can gracefully degrade to old payment path via feature flag if new service fails.
Four-Stage Playbook: Stages A–D per provider. Stage C (write) is highest-risk; ensure golden master passes 100% and shadow mode shows zero divergence before each provider cutover. Gate and soak strictly: four weeks minimum before any freeze.
Soak and Timing: Land in open window (Feb–May or Aug–Nov). Complete all three providers' Stage C cutover by month 9 to allow checkout orchestration time to soak before freeze.
15. Extract Orders: Event-Sourced Record of Truth (after 9, 13, 14) new
Extract order management as authoritative record of order lifecycle. Extracted after Inventory, Pricing, and Payment exist and are stable, because Orders depends on all three.
Orders Service: Own order tables and order state machine. Implement explicit state transitions: Pending → Confirmed → Preparing → Shipped → Delivered, with validation blocking invalid transitions. Design API: CreateOrder(cartId, customerId, paymentAuthorizationId), GetOrder(orderId), CancelOrder(orderId), UpdateOrderStatus.
Event Sourcing: Record all order state changes as immutable events. Build order state from event log on demand. Audit trail satisfies regulators and fulfillment teams; state can be rebuilt after incidents. Include: OrderCreated, PaymentAuthorized, InventoryReserved, OrderConfirmed, OrderPreparing, OrderShipped, OrderDelivered, OrderCancelled.
Event Consumption: Consume events from Payment service (PaymentAuthorized, PaymentFailed), Inventory service (StockReserved, ReservationCancelled), and Returns service (ReturnInitiated, RefundIssued) rather than polling or joining.
Four-Stage Playbook: Stages A–D. Stage A (shadow) for 1 week. Stage B (read cutover) for 2 weeks, with gradual flag ramp. Five teams that query orders start reading from Orders service via API. Stage C (write cutover): new orders written to Orders service; monolith order tables become reverse-CDC read-only replicas. Stage D after one peak.
Reconciliation: Monetary and Row-Count: Reconcile order counts and monetary totals hourly against monolith throughout transition. Currency totals must match exactly (cent-by-cent); row count discrepancies are immediate rollback. Implement automated reconciliation query; owner assigned; threshold zero.
Concurrent Order Transitions: Load-test concurrent order state transitions at 480k/day peak. Order state machine becomes serialization point for distributed system; ensure no race conditions, no duplicate orders, no lost transactions.
Soak Before Checkout: Complete Orders cutover (Stages A–C) by month 9. Soak minimum four weeks before freeze. Gate to proceeding to Checkout (Step 16) is four-week soak with zero monetary reconciliation mismatches and zero order duplicates.
16. Extract Checkout: Distributed Saga Orchestration (Highest Risk) (after 12, 13, 14, 15) from P3 step 10
Highest-risk extraction, deliberately placed last among transactional work and only after components it orchestrates are individually proven at scale. This step composes independent services into coherent checkout flow.
Checkout Orchestrator Service: Build service that coordinates checkout: cart validation, price computation, inventory reservation, payment authorization, order creation. Design as explicit saga with named steps and compensating actions.
Saga Orchestration: Implement synchronous saga (single coordinator) or asynchronous (choreography via events), chosen based on latency testing (target checkout p99 < 5 seconds at peak). Synchronous preferred for checkout because customer waits; failure is visible. Steps:
- Validate cart via Cart service
- Compute price via Pricing service (cached if < 1 second old)
- Reserve inventory via Inventory service
- Authorize payment via Payment service
- Create order via Orders service
Compensating Transactions: For every step, define compensation:
- Step 3 fails: Release inventory reservation
- Step 4 fails: Release inventory reservation, void authorization (if possible)
- Step 5 fails: Release reservation, void authorization, return payment to customer
- Step 2 recomputes and differs: Increase price, reject order; or decrease price, accept at old price (business rules decision, document explicitly)
Idempotency End-to-End: Checkout request includes idempotency key (unique per browser session + timestamp). Service deduplicates on this key. Retried checkout cannot double-charge or double-reserve; returns previous result.
Timeout Handling: Inventory reservation expires in 15 minutes (configurable). Payment authorization valid for 7 days (provider-specific). Order creation never times out; if hanging, manually investigate. Saga must fail safe to retryable state, never to half-committed order.
Shadow Traffic Before Live: Mirror live checkout traffic (100% of checkout requests during business hours) to new orchestration for minimum 2 weeks before any live cutover. Compare full outcomes: order ID, order total, inventory reservations, payment authorization IDs, error messages. Divergence > 0.001% blocks live cutover.
Live Ramp During Open Window: Ramp live traffic only during open delivery window (Feb–May or Aug–Nov). Gate and soak strictly: minimum four weeks before freeze. Keep monolith checkout path fully functional and warm (receiving live traffic via feature flag) as rollback target until Checkout service has survived one full peak.
Peak-Readiness Gate Mandatory: Hold six-week peak-readiness gate (Step 19) before proceeding to back-office migration (Step 18). Failed gate stops this work immediately and defers to next window.
17. Migrate Back-Office, Storefront, and Mobile Clients to Service APIs (after 16) from P2 step 17
Moves 300 back-office staff and client applications off monolith database direct access. Until this step, monolith database remains live dependency even where logic moved.
Back-Office Screen Refactoring: Migrate screens table by table. Replace direct SQL with service API calls through gateway. Start with orders (call Orders service), then customers (call Customer service), then inventory (call Inventory service). Build aggregation endpoints: /orders/{id}/full-details calls Orders + Payments + Inventory + Returns services, caches 30 seconds, returns unified response.
Aggregation Endpoints and Caching: Services are now call-chain away, not co-located. Back-office latency would suffer without caching. Implement short-lived cache (TTL 30 seconds) for frequently accessed data (customer profiles, recent orders). Graceful degradation: if one service slow, show cached data and alert staff.
Storefront and Mobile App: Both hit same endpoints (via gateway). Update storefront (server-rendered) to call service APIs while keeping old path functional behind feature flag; rendering regression becomes flag flip, not rollback. Mobile app points at gateway for migrated endpoints; keep old endpoints alive for un-updated app versions (users do not upgrade on schedule). Implement API versioning: v1 (legacy monolith), v2 (service APIs); clients request version in Accept header.
API Versioning and Deprecation Windows: Publish versioning rules: breaking changes trigger major version bump (v2 → v3). Old version supported for minimum 90 days after major release. Client teams must upgrade within window; do not force upgrade. Document deprecation timeline in API spec.
Load Test Back-Office Concurrency: Test 300 concurrent staff on top of peak storefront (480k orders/day). New services now carry both loads; autoscaling and database connection pools must handle burst. Simulate realistic staff queries: order searches, customer history, bulk refunds.
Distributed Tracing for Debugging: Every back-office request traced across services. Staff can view trace in UI; operations team can see which service was slow. Trace includes: request start, service calls, database queries, cache hits/misses.
Monitoring and Runbooks: Create runbooks for common issues: slow customer search (check Customer service load), payment lookup fails (check Payment service), order create fails (check Orders service latency). Link from dashboard to runbook.
Gate to Monolith Decommissioning: Back-office must be fully migrated (no direct SQL reads to monolith) before monolith core decommissioning (Step 18). This step completes organizational cutover.
18. Chaos Engineering, Resilience Testing, and Pre-Peak Validation (after 17) new
Validates new distributed architecture survives failure scenarios and peak load without cascading collapse. This step is as much about proving state is coherent as about finding failure modes.
Chaos Game Days: Scheduled monthly (or before each peak). Kill each service in turn (Search, Inventory, Orders, Payments, etc.); confirm storefront degrades gracefully (e.g., 'Search temporarily unavailable, catalog browsing still available') rather than failing completely. Kill database replicas; verify service continues with read-only or cached data. Kill message broker; verify no events lost and no reordering. Record each game day; publish findings and mitigation actions.
Peak-Readiness Gate (Before Each Peak): Run six weeks before January and July peaks (mid-November, mid-May):
- 12x Load Test: Generate realistic 480k orders/day traffic against production-shaped data (8 countries, 3 currencies, 4 languages, realistic product hierarchy). Measure checkout p99 < 5 seconds, search p95 < 1 second, payment < 2 seconds.
- Capacity Headroom: Confirm all services autoscale to handle 12x baseline. Database connection pools have headroom. Message broker partitions are sufficient. Cache hit rates do not collapse under load.
- Rollback Rehearsal: Execute full rollback of most recent service extraction in load-test environment. Measure rollback time; must be < 30 minutes including data reconciliation.
- Error Budget Review: Confirm SLO error budgets not burned significantly. If burned, identify culprit and mitigate before peak.
- Evidence Publication: Publish load-test results, capacity headroom metrics, rollback time, and SLO status. Gate is pass/fail; failed gate defers peak exposure and triggers root-cause work.
Full System Load Test: All services under load simultaneously. Measure inter-service latencies, database load, message broker throughput. Identify bottlenecks: pricing calculations, search queries, payment provider round-trip time, inventory reservations under concurrent access. Tune:
- Database query indexes
- Connection pool sizes
- Caching strategies
- Message broker partitions
- Service autoscaling thresholds
Failure Mode Analysis: Identify top 10 single-point-of-failure risks:
- Payment provider outage → graceful degradation (pre-authorize smaller amounts?)
- Inventory service down → checkout blocked; mitigation: cache inventory in checkout orchestrator
- Pricing service down → checkout blocked; mitigation: cache last-known prices
- Orders service down → checkout blocked; mitigation: queue orders in Kafka, replay when service recovers
- Database down → all services blocked; mitigation: read-only replicas for queries
- Message broker down → no events published; mitigation: outbox patterns ensure no event loss
- API gateway down → all traffic blocked; mitigation: active-active gateway setup (two regions or multiple providers)
- Warehouse sync delayed → inventory stale; mitigation: alert threshold, manual intervention process
- Customer service down → login blocked; mitigation: cache tokens, allow anonymous checkout
- Search service down → browsing blocked; mitigation: fallback to category list without search
For each failure, document mitigation (architectural change or operational procedure), test in chaos game day, and update runbooks.
Synthetic Transaction Monitoring: Implement real-world checkout, return, and search transactions executing every five minutes. Alert on failure before customers notice. Include multi-country, multi-currency variations.
Performance Baseline Documentation: Document baseline latencies (checkout, search, payment) at baseline load (40k orders/day). Load test must show no regression at peak; improvements accepted. Document these baselines in runbooks for operations team reference.
19. Monolith Decommissioning and Steady-State Operations (after 18)
Safely retire monolith code once all services stable and production-proven. This step is final validation that new architecture is coherent; incomplete decommissioning signals hidden coupling.
Module-by-Module Cleanup: Delete extracted service code from monolith only after that service has survived one full peak (January or July, whichever comes first) or four clean weeks post-cutover, whichever is longer. Before deletion:
- Audit dead code: which stored procedures, views, tables, methods are no longer called
- Verify service API is the only interface for data owned by extracted module
- Confirm no service calls back into monolith code
- Delete extracted logic and dependencies
Database Decommissioning: Dropped tables are archived (not deleted) for 90 days (regulatory retention and emergency queries). After 90 days, drop and archive to long-term storage. Monolith database shrinks as modules extracted. When monolith becomes shell (mostly unused), decide: keep as fallback or shut down entirely.
Cross-Module Stored Procedures: All stored procedures touching multiple modules' tables must be eliminated before monolith shutdown. If any remain, move logic into services or refactor. Document any that cannot be moved; escalate as risk.
Backup and Recovery Procedures: Shift from single monolith snapshot to per-service snapshots. Each service team owns backup/recovery for their database. Document recovery procedures: which services recover in which order, which can tolerate data loss vs. which require point-in-time recovery. Test recovery monthly.
Architectural Decision Records: Publish final ADRs documenting:
- Why services were split at these boundaries
- What problems each split solved
- What trade-offs were made
- What cross-service communication patterns emerged
- What monitoring and alerting proved most useful
Operational Runbooks: Finalize runbooks for each team:
- Incident response: common failure modes, resolution steps, escalation paths
- Deployment procedures: how to deploy service, rollback procedure, expected latency
- On-call procedures: alert thresholds, page-worthy events, war room communication
- Database procedures: backup, restore, schema migrations, connection pool tuning
Service Ownership Model: Confirm each of five teams owns one or more services end-to-end:
- Codebase and CI/CD pipeline
- Database schema and migrations
- On-call rotation and SLOs
- Production incidents
- Capacity planning and scaling
No shared ownership; clear escalation paths between teams.
Team Ramp-Down of Migration Work: Migration enablement squad (formed in Step 1) transitions into steady-state platform team. Reduce migration velocity; redirect capacity to feature work on services.
Exit Criteria and Project Close:
- All rungs 1–6 of scope ladder complete (or deliberately stopped at rung boundary)
- Both peak seasons (January and July) survived without migration-caused incidents
- All services deployed independently by month 12
- Monolith reduced to < 5% of original codebase or decommissioned entirely
- All architectural decisions documented and team alignment confirmed
Celebrate and Document Lessons: Publish retrospective capturing:
- What went well: which techniques proved most valuable (golden master? chaos testing? soak periods?)
- What was hard: which services took longer, which risks materialized
- What would change next time
- Which rungs of scope ladder were reached and why work stopped where it did
Deferred Work: Explicitly list architectural or optimization work deferred to follow-up programs (e.g., Pricing DSL refactoring, read-write split at database level, multi-region deployment).
20. Peak Season Validation and Post-Peak Stabilization (after 18, 19) new
Proves new architecture survives peak and validates migration is truly complete. January and July peaks are the final test; this step verifies readiness and documents learnings.
Pre-Peak Confirmation: One week before peak start (Dec 25 for January peak, June 25 for July peak), confirm:
- All peak-readiness gate checks passed
- All services healthy and responding normally
- Database connection pools at capacity
- Cache hit rates normal
- Message broker lag within SLOs
- On-call rotations staffed
- War room communication channels open
Peak Monitoring: During peak (480k orders/day sustained for 2–3 weeks), maintain heightened monitoring:
- Every service dashboard visible in central war room
- Latency p99, p95, p50 trending in real time
- Error rate per service alarmed
- Database query performance monitored
- Message broker lag tracked
- Payment success rate watched (fraud filters, authorizations)
- Inventory reservation accuracy validated hourly
Incident Response: Any incident < 5 min MTTR automatically escalates to war room. Team lead validates:
- Root cause (service slow? database? payment provider?)
- Impact (customer-visible? checkout blocked? data corruption?)
- Mitigation (rollback flag? scale service? throttle traffic?)
- Recovery (how long to resolve?)
Post-Peak Retrospectives: Within one week of peak completion, each service team retrospectives on:
- Peak traffic patterns observed vs. load-test simulations
- Any incidents: root cause, time-to-detect, time-to-recover
- Performance variations: which services scaled, which became bottlenecks
- Data accuracy: any reconciliation mismatches discovered during peak
- Lessons for next peak
Capacity Planning: After peak, analyze:
- Database query times at peak: any unexpected slowdowns?
- Service autoscaling: did services scale early enough? were there cascading failures?
- Cache effectiveness: hit rates at peak vs. baseline
- Message broker: any message loss or reordering?
- Payment provider latency: did provider response times increase during peak?
Final Validation: Confirm scope ladder rung achieved:
- Rung 6 complete: back-office migrated, monolith core reduced, checkout orchestration stable
- Teams deployed independently during peak (or blocked from deploying due to freeze, which is correct)
- Zero unplanned downtime caused by migration
- All rollback procedures worked in chaos testing; never needed in production
Program Closure: Publish final evidence:
- Peak season metrics (order volume, success rate, latency, errors)
- Service-by-service stability (uptime, incidents, MTTR)
- Scope ladder rung reached
- Explicit deferred work list
- Team feedback and lessons learned
Next Program Planning: If rung 7+ desired (e.g., Pricing rules DSL refactoring, multi-region deployment), plan as separate 6-month program. Document in writing; do not creep scope into current program.
- Zero unplanned downtime: 100% availability throughout 12-month migration (excluding planned 30-min blue-green deployments); no production incidents attributable to migration architecture
- Peak seasons protected: January and July peaks (480k orders/day) sustain zero degradation caused by migration; checkout p99 ≤ 5 seconds, payment authorization ≤ 2 seconds, error rate ≤ 0.5%, no queue backlog > 5 minutes
- Independent deployability: All eight services independently deployable by month 12; each team releases on own cadence (weekly or faster) with zero cross-team deployment coordination; 100% of service releases verified rollback-capable in < 30 minutes
- Rollback-proven: Every production increment has rehearsed, documented, tested rollback path (expand/contract migrations, feature flags, reverse CDC); monthly chaos game days validate rollback procedures; zero increments reach production without passing rollback gate
- Data consistency: Hourly reconciliation shows < 0.001% row-count and checksum discrepancy between service databases and monolith (pre-decommissioning); zero business-invariant violations (no duplicate orders, no lost payments, no inventory oversells)
- Pricing correctness: 100% agreement between new Pricing service and golden-master corpus across 1M+ historical requests covering all 8 countries, 3 currencies, 4 languages, all promotion types; zero pricing errors post-cutover
- Search freshness: Product availability reflects in search within < 60 seconds of inventory change (vs. nightly rebuild); search latency p95 unchanged or improved at peak load
- Warehouse sync improvement: Inventory synchronization lag reduced from 15 minutes to < 2 minutes end-to-end; 100% of daily warehouse updates processed; no missed sync cycles during migration
- Payment processing: Zero regressions with all three payment providers; fraud detection active and effective; PCI-DSS compliance maintained; idempotency prevents duplicate charges; payment success rate ≥ 99.5% at peak
- Back-office operations unaffected: All 300 staff seamlessly using service APIs; service aggregation endpoints maintain p95 latency ≤ 500 ms; bulk operations (refunds, order status updates) complete within SLA
- Test coverage for services: All newly written service code reaches 80%+ line coverage; golden master validates 100% of public API contracts before production traffic; contract tests (Pact) prevent breaking changes between services
- Peak-readiness gate passed: Six weeks before each peak (mid-November, mid-May), gate published showing 12x load test results, capacity headroom, rollback rehearsal duration, and SLO status; failed gate defers work; evidence published publicly
- Team independence by month 12: Five teams deployed independently; each owns service codebase, pipeline, database schema, on-call rotation, SLOs; no cross-team pull requests blocking releases; internal developer platform (golden-path templates, self-service deployments) adopted by all teams
- Scope ladder completed: Rungs 1–6 reached by month 12 (or deliberately stopped at rung boundary with documented justification); all services proven at peak; monolith reduced to < 5% or decommissioned
- Calendar adherence: No major extractions or refactors during freeze windows (Dec 1–Jan 15, June 1–July 15); all production increments land in open windows with minimum 4-week soak before freeze; timeline published and adhered to
- Event-driven architecture validated: Kafka message broker handles 480k+ messages/day at peak; no message loss, no ordering violations; outbox pattern ensures every domain event persists atomically
- Fallback capacity maintained: Monolith rollback path kept warm and functional (receiving live traffic or ready-to-receive via feature flag) until each service survives one full peak; no service extracted without proven rollback capability
[SYSTEM]
You are an expert assistant in complex project planning.
Your task is to generate a detailed and structured action plan to reach the main objective in the most professional and most detailed way, no matter how much work or steps will be needed to perform.
Use your internal reasoning processes to think deeply about the problem and create the most comprehensive plan possible.
Take as much time and space as you need to think through all aspects of the problem.
After your thorough analysis, answer with the plan in the requested structure.
Every text field you write will be read by a busy person, so write for them: short sentences, one idea each, in short paragraphs. Text fields accept Markdown: separate paragraphs with a blank line, use a bullet list when you enumerate things and plain paragraphs when you explain or argue, and bold at most one key phrase per paragraph. A text of more than three sentences must be split into paragraphs; never deliver a single unbroken block of text.
[HUMAN]
Main Objective: "A mid-size European fashion retailer runs its e-commerce on a 10-year-old monolith: Java 8 / Spring, about 2 million lines, one PostgreSQL database of 1.2 TB with 350 tables and heavy use of stored procedures and cross-module joins. It serves 8 countries, 3 currencies and 4 languages, with about 40,000 orders a day and peaks of 12x during sales. The monolith contains: the storefront (server-rendered, plus a separate mobile app hitting the same endpoints), catalogue and search (a Lucene index rebuilt nightly), pricing and promotions (the most complex module, 200,000 lines, with country-specific rules nobody fully understands), cart and checkout with three payment providers, order management, inventory synchronised every 15 minutes with the warehouse system via file exchange, customer accounts and loyalty, returns, and a back-office used by 300 staff. Deployments happen every two weeks as a single artefact with a 30-minute maintenance window; test coverage is 25% and mostly unit tests. Five teams of 8 developers, each organised around a business area but all committing to the same repository.
Plan the migration to independently deployable services over 12 months with no feature freeze, no unplanned downtime and the ability to roll back every step, preserving the peak-season capacity (sales in January and July must not be put at risk)."
For your consideration and refinement, here are proposals from the previous round:
Previous Proposal 1 (ID: e20ff2ba-878c-44ab-b4e7-a66d5715df9c, Agent: claudeHaiku4.5_refine_1 - YOUR OWN previous proposal, LLM: anthropic/claude-haiku-4-5):
Estimated Complexity: high
Success Metrics: - Zero unplanned downtime during 12-month migration; all maintenance windows scheduled and communicated; zero production incidents caused by migration
- Peak seasons (January and July sales) proceed with zero degradation: 480k orders/day processed with p95 checkout latency < 5 seconds, payment authorization < 2 seconds, zero payment processing failures
- All eight services independently deployable: no code commits force monolith downtime; new service deployment < 5 minutes; deployment frequency increases from bi-weekly (monolith) to daily (services) where applicable
- Test coverage increased from 25% to 70%+ for all extracted services (Search, Inventory, Customer, Cart, Orders, Payments, Returns); characterization test suite for Pricing passes 100% before service extraction
- Every service deployment is rollback-able in < 30 minutes: documented procedures tested monthly; rollback automated where possible
- Data consistency validated: monthly reconciliation between service databases and monolith shows zero inconsistencies; dual-write period completes successfully (2 weeks per service)
- Order processing SLA maintained: cart → confirmation latency unchanged or improved; maintained under 5 seconds at peak load (480k orders/day)
- All five teams deploying independently by month 12: no cross-team deployment coordination required; each team owns service, deployment pipeline, on-call rotation
- Search latency improved or maintained: product availability reflected in search results within < 1 minute of inventory update (vs. previous nightly rebuild), baseline latency unchanged
- Inventory synchronization preserved: no missed 15-minute warehouse sync cycles during migration; 100% of daily inventory updates processed
- Back-office operations unaffected: 300 staff members seamlessly using new service APIs; service aggregation endpoints maintain < 500ms p95 latency
- Payment processing: zero regressions with all three payment providers; fraud detection remains active; PCI-DSS compliance maintained; idempotency prevents duplicate charges
- Event-driven architecture validated: Kafka message broker handles 480k messages/day at peak; no message loss or ordering violations
- Rollback capability proven: every step validated to be reversible; no permanent cutover without 30-day validation period and green light from peak season calendar
Steps (20):
1. Platform Foundation: Kubernetes, CI/CD, and Observability
Establish the technical foundation for independent service deployment and operation before touching the monolith architecture.
- Provision Kubernetes cluster with dev/staging/prod namespaces, or equivalent managed cloud platform (ECS/App Engine)
- Deploy centralized logging (ELK or Loki), metrics (Prometheus/Grafana), and distributed tracing (Jaeger)
- Implement CI/CD pipelines for independent service deployments (GitHub Actions/GitLab CI/ArgoCD)
- Set up secrets management (Vault) and configuration management (Consul/Spring Cloud Config)
- Create observability dashboards for: order throughput, latency percentiles (P50/P95/P99), error rates, database load
- Define SLOs and alerting: order processing latency p99 < 5 seconds, checkout success rate > 99.5%, payment auth speed < 2 seconds
2. Strangler Pattern Setup: API Gateway, Feature Flags, and Service Mesh (depends on: 1)
Deploy the infrastructure layer that enables gradual traffic migration from monolith to services without downtime.
- Deploy API gateway (Kong or AWS ALB) in front of monolith; all traffic routes through gateway
- Implement feature flag system (LaunchDarkly or Unleash) to decouple deployment from traffic routing
- Set up service mesh (Istio or Linkerd) for inter-service communication, mTLS, and circuit breakers
- Containerize monolith as-is (Docker) so it can run alongside new services
- Instrument monolith with event publishing capability: add transactional outbox table for domain events
- Create blast radius containment: rate limiting, bulkheads, and timeouts at gateway level
3. Domain Analysis and Service Boundary Definition via Event Storming (depends on: 2)
Map the monolith's business domains and dependencies to identify safe extraction sequence and service boundaries.
- Run event storming workshops with all five teams; map customer journeys (Browse → Cart → Checkout → Order → Fulfillment → Returns)
- Create dependency matrix: which tables, stored procedures, and methods are accessed by each domain
- Use code hotspot analysis (SonarQube, CodeScene) to find logical coupling and identify decoupling opportunities
- Define service extraction sequence based on coupling and business risk: prioritize read-heavy (Search), well-bounded (Inventory), and identity (Customer) over complex (Pricing, Checkout)
- Document all cross-module joins; mark which ones must be eliminated vs. which can tolerate eventual consistency
- Identify stored procedures that span multiple domains; plan refactoring or replication strategy
4. Peak Season Protection Framework and Change Freeze Calendar (depends on: 3)
Establish hard boundaries to protect January and July sales from destabilizing changes.
- Map annual peak periods: January sales (peak revenue), July sales, plus promotional events
- Define 6-week freeze windows: 4 weeks before + 2 weeks during each peak season; no major extractions or refactors during freeze
- Identify lowest-risk windows in each month for incremental changes (hotfixes, small extractions, data migrations only)
- Create rollback runbooks for every step: how to revert traffic routing, database changes, and service deployments in < 30 minutes
- Establish incident escalation and communication plan: business owners notified of any changes near peak season
- Plan load testing outside freeze windows: validate 12x capacity (480k orders/day) for each service before peak season
5. Pricing Module Characterization: Black Box Baseline and Test Suite (depends on: 3)
Thoroughly document the 200k LOC pricing engine behavior before any extraction attempt, eliminating unknown risk.
- Analyze and document all pricing rules: country-specific logic, currency handling, promotional rules, edge cases
- Create comprehensive characterization test suite: record input/output for all 8 countries × 3 currencies × major promotional scenarios
- This test suite becomes the 'golden master': any new pricing service must match 100% of outputs
- Build test data set covering: normal pricing, discounts, bulk pricing, regional pricing, multi-currency edge cases, seasonal promotions
- Document all dependencies: which customer attributes, product attributes, inventory levels, and time-based factors affect pricing
- Establish CI gate: pricing service extraction cannot proceed until characterization tests pass 100%
6. Test Coverage Improvement: Target 70% for Extract-Candidate Modules (depends on: 3)
Increase test confidence for modules scheduled for early extraction; reduce rollback risk from test blindness.
- Audit current test coverage by module; identify gaps in: Search, Catalogue, Inventory, Cart, Customer
- Implement integration tests for critical flows: order creation, payment processing, inventory updates, customer account creation
- Add contract tests (Pact) between modules to catch API breaking changes early
- Use mutation testing to verify test quality: tests must catch injected bugs
- Target 70%+ coverage for Search, Inventory, Customer, Cart, Payments modules
- Establish automated quality gates: no service extraction if module coverage < 60%; no production deployment if < 70%
- Create load test suites for peak scenarios: simulate 40k→480k order escalation for each module
7. Change Data Capture and Event-Driven Data Sync Infrastructure (depends on: 2, 5)
Build the plumbing to eliminate cross-module database joins and enable eventual consistency between services.
- Deploy CDC tool (Debezium with Kafka/Pulsar) to stream PostgreSQL WAL changes to message broker
- Refactor monolith to use transactional outbox pattern: all domain events written atomically in same transaction as business data
- Create event schema versioning: events must be backwards/forwards compatible as services evolve
- Implement dual-write mechanism: during transition, write to both monolith database and new service database
- Set up event relay: monolith publishes events (OrderPlaced, PaymentAuthorized, InventoryReserved) to Kafka
- Define eventual consistency model: which operations can tolerate delayed propagation vs. which require immediate consistency
8. Search and Catalogue Service Extraction: Read-Heavy Pilot Service (depends on: 6, 7)
Extract the first service: read-heavy, low transactional risk, validates the entire strangler fig pattern.
- Build new Catalogue and Search service: REST API for product lookup, search, and filtering
- Create new database schema (PostgreSQL): product data, categories, attributes; use Elasticsearch/OpenSearch for real-time search indexing
- Subscribe to CDC events from monolith: ProductUpdated events trigger real-time search index refresh (eliminates nightly Lucene rebuild, improves freshness to < 1 minute)
- Implement dual-read path: feature flag controls whether requests hit monolith Lucene or new Search service
- Use API gateway shadow traffic: send requests to both old and new service; compare responses; alert on differences
- Gradually shift traffic: 10% → 25% → 50% → 100% using feature flags and canary deployments
- Maintain dual-write for 2 weeks post-cutover to verify correctness; then deprecate monolith search code
9. Inventory Service Extraction: Real-Time Warehouse Synchronization (depends on: 7, 8)
Extract inventory as second service: async boundary, directly integrates with warehouse system, eliminates 15-minute sync latency.
- Build Inventory service: consumes warehouse file feed (SFTP/API) directly instead of monolith polling
- Create inventory database schema: stock levels, reservations, holds per product per location
- Publish inventory events: StockLevelChanged, ReservationCreated, ReservationReleased to Kafka
- Implement reservation system (prepare for saga pattern): inventory holds items during checkout, releases on order confirmation or timeout
- Dual-write monolith inventory data during transition: maintain consistency between old and new
- Test warehouse sync at peak load: ensure 15-minute sync windows do not slip under 480k daily orders
- Validate that all cart and checkout code calls inventory service via API (or consumes events) rather than direct SQL join
- Gradual traffic shift: test with non-critical inventory queries first, then critical paths
10. Customer and Loyalty Service Extraction: Identity Decoupling (depends on: 9)
Extract customer accounts and loyalty programs: enables independent auth scaling and multi-tenant loyalty rules.
- Build Customer service: JWT token generation, profile management, address management, identity verification
- Create customer database schema (separate from monolith): User, Address, Profile; replicate to read-only cache where needed
- Implement loyalty points service: handles country-specific loyalty rules (8 countries, different point accrual rates)
- Sync customer data via events: monolith publishes CustomerCreated, CustomerUpdated, CustomerDeleted to Kafka
- API gateway routes: /api/login, /api/profile, /api/loyalty to new Customer service; monolith drops these endpoints
- Ensure backwards compatibility: versioned API responses so old mobile app clients still work
- Test at peak concurrency: concurrent logins, loyalty point updates under 480k orders/day load
- Implement session management: distributed sessions (Redis-backed) so users stay logged in during monolith↔service transitions
11. Saga Pattern Framework and Distributed Transaction Orchestration (depends on: 7)
Implement the orchestration layer required for multi-service transactions before extracting payment and order services.
- Build saga pattern library: support both choreography (event-driven) and orchestration (centralized coordinator) patterns
- Implement compensating transactions: if payment fails during checkout, inventory reservation and pricing calc must roll back
- Add idempotency framework: all services accept idempotency-key headers; prevent duplicate charges, double-deductions
- Handle timeouts and retries: exponential backoff, circuit breakers, manual intervention for stuck sagas
- Create saga log: record saga execution with state transitions for auditing, debugging, and replay
- Test saga execution under peak load and network failures: simulate payment provider latency, inventory service timeouts
- Document saga flows: checkout saga (price → reserve inventory → authorize payment → create order), return saga, refund saga
- Implement distributed tracing: each saga step is traced end-to-end for observability
12. Payment Service Extraction: PCI-Scoped and Secure (depends on: 11)
Extract payment processing with extreme security rigor: handles card data, three payment providers, regulatory compliance.
- Build Payment service: integration with all three payment providers (tokenization, authorization, capture, refund)
- Implement PCI-DSS compliance: no raw card data in logs, encrypted transport, minimal data exposure in monolith
- Handle payment declines and fraud: integrate fraud detection, implement retry logic for transient failures
- Create idempotent payment requests: prevent double-charging if client retries or network fails mid-request
- Implement webhook handling: payment providers notify service of async events (captures, chargebacks, refunds)
- Design rollback procedure: if new service fails catastrophically, fall back to direct monolith payment handling (via feature flag)
- Load test: 500+ payments/sec at peak (baseline 40k orders/day → 480k orders/day = ~550 payments/sec)
- Test all three provider scenarios: happy path, declines, timeouts, chargebacks
13. Orders Service Extraction: Orchestrator for Checkout and Fulfillment (depends on: 12)
Extract order management: central service coordinating checkout saga and order lifecycle across all services.
- Build Order service: order creation, status tracking, order querying API for all business users (inventory, fulfillment, customer service teams)
- Implement checkout orchestrator: accepts cart (items, customer, delivery address) → triggers saga → creates order record on success
- Integrate with Payment service (authorize payment), Inventory service (reserve stock), Pricing service (calculate total), Customer service (loyalty points)
- Implement order state machine: validate state transitions (Pending → Confirmed → Shipped → Delivered), prevent invalid transitions
- Create order event stream: OrderCreated, PaymentAuthorized, InventoryReserved, OrderConfirmed, OrderShipped for other services to consume
- Use event sourcing: maintain immutable log of all order state changes for audit trail and replay capability
- Test concurrent order processing at peak load: 40k→480k orders/day; ensure no race conditions, duplicate orders, or lost transactions
- API design: query orders by customer ID, order ID, SKU, date range; sorting and filtering for back-office use
14. Cart Service Extraction: Stateful Session Management (depends on: 10)
Extract shopping cart as stateful service: decouples browsing/cart operations from order processing, independent scaling.
- Build Cart service: add/remove items, update quantities, persist session state, apply coupons/discounts
- Implement cart storage: Redis for session-backed stateless carts, or PostgreSQL with session affinity for persistent carts
- Integration with services: calls Catalogue service (product availability), Inventory service (stock check), Pricing service (cart totals)
- API design: cart operations (add/remove/view), subtotals with pricing breakdowns, coupon application
- Implement session stickiness: API gateway routes same user to same Cart service instance (or share Redis state)
- Test at peak concurrency: concurrent cart updates from same user (one browser tab → mobile app → browser again)
- Ensure idempotency: adding same item twice returns same cart state, no duplicates
- Gradual traffic shift: test with non-critical users first, then ramp up
15. Pricing Service Extraction: Black Box Wrapping and Golden Master Validation (depends on: 5, 13)
Extract pricing logic as black box service using characterization tests to ensure 100% correctness preservation.
- Move 200k LOC pricing logic into dedicated Pricing service with own codebase
- Service exposes API: accepts product IDs, customer attributes, location, time, inventory levels → returns price, applicable promotions, currency
- Use dedicated read-replica database with pricing tables only (no cross-joins to other domains)
- Run shadow mode traffic: send live pricing requests to both old monolith and new service; compare outputs; alert on any divergence
- Validation gate: pricing service must match characterization test suite 100% for all 8 countries, 3 currencies, all tested scenarios
- Feature flag control: gradually shift production traffic once shadow mode validates correctness
- Document decision: this service remains a black box (we don't refactor internal logic); future teams can safely extend without fear
- Plan Phase 2 refactoring separately: after service is stable in production, optionally decompose into rules engine (Drools) in future quarter
16. Returns Service Extraction and Order Lifecycle Completion (depends on: 13, 15)
Extract returns handling: completes order lifecycle, depends on Orders and Pricing services being stable.
- Build Returns service: process return requests, validate return eligibility, calculate refunds (using Pricing service), manage return shipping
- Integrate with Orders service: fetch order data, verify items purchased
- Integrate with Inventory service: return items to stock after confirmation
- Integrate with Payment service: process refunds back to original payment method
- API design: create return request, track return status, generate return shipping labels
- Implement return state machine: Requested → Approved → Shipped → Received → Refunded
- Consumer integration: back-office staff (or customer self-service) calls Returns service APIs instead of monolith
- Test return flows at peak load: validate no inventory/refund race conditions
17. Back-Office Service Aggregation and Staff User Experience (depends on: 13, 16)
Update back-office (300 staff) to consume new service APIs; eliminate monolith direct database access.
- Create service aggregation endpoints: orders endpoint calls Order + Payment + Inventory + Shipping services; returns endpoint calls Returns service
- Implement API gateway service discovery: back-office transparently calls services even if they move/scale
- Add caching layer: frequently accessed data (customer profiles, order lists) cached with TTL to reduce service latency
- Implement timeouts and graceful degradation: if one service is slow, show cached data or partial results
- Refactor back-office UI: replace monolith SQL queries with REST API calls
- Test with 300 concurrent staff users: search across orders/customers, filtering by date/status, bulk actions
- Implement distributed tracing: back-office requests are traced across all services for debugging
- Add retry logic: transient failures (network blips) automatically retry; permanent failures show user-friendly errors
18. Load Testing and Peak Capacity Validation Across Full System (depends on: 17)
Validate new distributed architecture handles peak load (480k orders/day) without degradation; stress test before peak seasons.
- Simulate realistic peak load: 480k orders/day (12x baseline), 8 countries, 3 currencies, 4 languages simultaneously
- Test sequence: base load → ramp to 480k → sustain for 30 minutes → spike to 1.5x peak → graceful degradation
- Measure latencies: checkout flow (cart → confirmation) p95 < 5 seconds, payment authorization < 2 seconds, search < 1 second
- Monitor service-level metrics: requests/sec, error rates, database query times, message broker throughput, cache hit rates
- Identify and optimize bottlenecks: pricing calculations, search queries, payment provider round-trip time, inventory reservations
- Test database connection pools: ensure no exhaustion or deadlocks under peak load
- Validate message broker (Kafka): 480k messages/day throughput, latency, durability
- Create realistic user behavior: product browsing → search → add to cart → checkout flows, not just load
- Fail-over testing: kill one service (e.g., Search); verify system degrades gracefully, no cascading failures
- Load test outside freeze windows; complete before January/July peak seasons
19. Team Reorganization and Independent Deployment Readiness (depends on: 18)
Reorganize teams around services to enable independent deployments and long-term operational autonomy.
- Reorganize five teams: from business-function-based (Pricing team, Fulfillment team) to stream-aligned (Search Service team, Orders Service team)
- Assign service ownership: each team owns their service's codebase, CI/CD pipeline, database schema, on-call rotation, SLOs
- Implement internal developer platform (IDP): golden path templates, self-service deployments, secrets rotation, observability dashboards
- Establish SLOs per service: error budget, latency targets, availability targets
- Create cross-team API contracts: service teams sign off on API changes; breaking changes trigger communication plan
- Set up inter-service communication: API versioning, deprecation periods, backward compatibility requirements
- Plan on-call: each team on-call for their service; pager rotation, incident response training
- Document service dependencies: which services call which; upstream/downstream impact analysis
20. Monolith Decommissioning and Legacy Code Cleanup (depends on: 19)
Safely retire monolith code once all services are stable and production-proven.
- Audit monolith codebase: identify dead code (Search, Catalogue, Inventory, Customer, Orders, Payments, Cart, Returns logic)
- Delete extracted service code from monolith; remove dual-write logic once service has proven stable (30+ days in production)
- Gradually reduce monolith database: archive or migrate old tables, remove cross-module stored procedures
- Plan monolith decommissioning: if monolith becomes shell (mostly unused), decide: keep as fallback or shut down completely
- Maintain 90-day read-only archive of monolith database for emergency historical queries and regulatory retention
- Update backup/recovery procedures: shift from single monolith snapshot to per-service snapshots
- Document architectural decisions: why services were split this way, what problems were solved, what trade-offs were made
- Create incident playbooks: common failure modes, resolution steps, escalation paths
- Close out migration project: update runbooks, retire temporary monitoring, establish steady-state operational procedures
- Celebrate: migration complete, new architecture proven at peak load, five teams deploying independently
Previous Proposal 2 (ID: 7581d19b-0670-4204-bf95-b6568fbf7cd4, Agent: deepseek-flash_refine_2, LLM: deepseek/deepseek-flash):
Estimated Complexity: high
Success Metrics: - Independent deployability: 100% of releases to extracted services require no coordination with another team and no monolith release, demonstrated for at least 6 services by month 9.
- Independent deployability precedes extraction: at least 4 of the 5 teams release their own artefacts without being separate services by month 5.
- The 30-minute maintenance window is retired by month 6; no release after that date requires a planned outage.
- Deployment lead time from merge to production for a single service is 30 minutes or less, and each team releases at least 3 times per week by month 6.
- Zero unplanned downtime attributable to the migration across the 12 months; platform availability of 99.95% or better inside each peak window.
- Both January and July peaks pass with no migration-caused incident: 12x baseline load sustained, checkout p99 under 5 seconds, error rate under 0.5%, no queue backlog beyond 5 minutes.
- 100% of migration increments that reach production have a rollback demonstrated in a game day and executable in under 30 minutes.
- Hourly data reconciliation shows under 0.001% discrepancy on row counts and checksums per module, with zero unexplained business-invariant violations.
- Cross-module database joins and cross-module writes originating in application code are zero for every module at the moment it is extracted, enforced by database roles and CI checks rather than by review.
- Pricing parity: 100% agreement with the golden master on a corpus of at least 1,000,000 historical requests across all 8 countries, 3 currencies and 4 languages, both before and after cutover.
- Stored procedures touching more than one module's tables: zero for every extracted module.
- Search freshness improves from a nightly rebuild to under 30 seconds between a product change and its visibility in search results.
- Warehouse inventory freshness improves from 15 minutes to under 2 minutes end to end.
- 100% of public APIs of extracted services have golden-master or consumer-driven contract coverage; line coverage is tracked only for newly written service code, where it reaches 80%.
- The peak-readiness gate is passed with published evidence six weeks before both peaks, covering 100% of its defined checks.
- Scope ladder rungs 1–6 are complete within 12 months, or the program stops at a rung boundary in a documented, coherent, peak-safe state.
Steps (18):
1. Program setup, peak-aware calendar, rollback charter and scope ladder
Turns the brief's constraints into an operating rhythm that everything later obeys. The binding constraint in this objective is the calendar, not the technology, so the calendar is decided first.
- Run a two-week inception to baseline the current state: build time, deployment lead time, change failure rate, MTTR, MTTR, per-module change frequency, database load profile. Progress must be measurable, not asserted.
- Declare hard freezes from 1 December to 15 January and 1 June to 15 July. During a freeze only rollback-enabling and hardening changes are allowed.
- Confirm the two open delivery windows of the year (roughly February–May and August–November) and accept in writing that only these windows carry migration increments.
- Set the soak rule: no change on the checkout path lands within four weeks of a freeze; anything that would violate it is deferred to the next window.
- Define the peak-readiness gate that runs six weeks before each peak: 12x load test, capacity headroom check, rollback rehearsal, error-budget review. The gate is pass/fail and its evidence is published.
- Write the rollback charter: every increment ships an expand/contract database change, a feature-flag kill switch, and a rehearsal recorded in a game day. No go-live without a rehearsed rollback.
- Publish the scope ladder: a ranked list where rungs 1–6 deliver the core objective and rungs 7+ are optional. Slippage means stopping at a rung boundary, never mid-increment.
- Set the capacity budget at 40–50% of the five teams' capacity for migration alongside normal feature work, and staff the ladder to fit that budget rather than to fill the year.
- Create a migration enablement squad of six engineers drawn on rotation from the five teams. It owns the platform, the shared cuts and the risky shared data work.
2. Executable architecture map, table ownership and boundary enforcement (depends on: 1)
Produces an architecture map that the build itself enforces. Five teams committing to one repository will silently re-couple anything that is separated and not policed, so enforcement is part of the map, not a later step.
- Instrument the monolith with distributed tracing and let it run four weeks. Real call paths beat static imports for finding true coupling.
- Build a table-to-module and query-to-module map by parsing every SQL statement, ORM mapping and stored procedure in the codebase, cross-checked against the database's own query logs.
- Score each candidate service on four axes: coupling, transactional risk, change frequency and peak-path criticality. This ranking, not intuition, drives the extraction order.
- Assign every one of the 350 tables to exactly one owning module. Tables nobody can own are declared contested and scheduled into the data work of S7.
- Add ArchUnit rules to CI that fail the build on any new cross-module Java dependency, with existing violations frozen into a baseline file that may only shrink.
- Add a SQL linter to CI that fails on cross-module joins and cross-module writes, with the same shrinking baseline.
- Publish the target service list, the owning team per service, and the reasoning as architecture decision records.
- Hold a mid-program review at month six to re-rank the scope ladder using what the map actually showed. This is the one planned re-planning point of the program.
3. Delivery platform: per-module pipelines, gateway, feature flags, environments (depends on: 1, 2)
Builds the delivery and traffic machinery that makes every later step reversible. No module is extracted until its team can deploy, flag and route on its own.
- Extend the platform foundation on Kubernetes (or the existing container platform if one exists) with one namespace per service, quotas and autoscaling policies sized for a 12x peak.
- Put an API gateway in front of the monolith as the strangler entry point. Storefront, mobile and back-office traffic all flow through it from day one, even while it routes everything to the monolith.
- Give every module its own CI/CD pipeline and its own environment. The monolith keeps its current pipeline for hotfixes until S5 replaces it.
- Deploy a feature-flag service and require every new call path to be flag-guarded. Flags are the primary rollback instrument for the whole program.
- Introduce secrets management and per-environment configuration so changing behaviour never requires a monolith redeploy.
- Define golden-path templates for a new service: build, pipeline, observability, health checks, flag integration, database migration tool. Extraction must not start from a blank page.
- Reserve two permanent environments: a full-size production-like soak environment and a load-test environment capable of generating 12x traffic against production-shaped data.
4. Observability, business SLOs, error budgets and the automated rollback controller (depends on: 3)
Makes the system observable enough that a canary is judged automatically and reverted without a human guessing. This is the prerequisite for the rollback promise made in every later step.
- Deploy centralized logging, metrics and distributed tracing, with trace correlation working across the gateway, the monolith and every new service from the start.
- Instrument the monolith's blind spots: query latency by module, connection-pool saturation, Lucene rebuild duration, warehouse file-exchange lag.
- Define SLOs on business outcomes, not infrastructure: checkout success rate, order confirmation p99, search latency, payment authorisation rate, price computation latency, warehouse sync freshness.
- Attach an error budget to each SLO and write the policy: when a service burns budget, its rollout stops automatically and its flags revert. No negotiation during a peak.
- Build the rollback controller: on error-rate or latency divergence beyond threshold during a canary, the gateway shifts traffic back and flags are disabled without human action.
- Create per-service dashboards a tired engineer can read at 03:00, plus one program dashboard showing progress against the scope ladder.
5. Split the deployment unit and retire the 30-minute maintenance window (depends on: 2, 3)
Delivers the objective's headline — independently deployable units — before any process separation, by splitting the build and the release train while the code still runs together. This is the cheapest large win available and it removes the maintenance window.
- Split the single artefact into one build per owning module with a shared parent, so a module can be built, tested and released on its own.
- Allow modules to be released as separate artefacts on the existing runtime first. Independent deployability is a build and release property long before it is a topology property.
- Retire the two-week coordinated release train. Each team gets its own pipeline, cadence and on-call rota, with the gateway and schema compatibility as the contract between teams.
- Adopt expand/contract database migrations so schema and code changes no longer have to ship together.
- Replace the maintenance window with blue-green deployment on two identical stacks, traffic switched at the gateway and rollback performed by switching back.
- Measure and publish the result: deployment lead time, deployment frequency per team, and the share of releases that needed no coordination with another team.
6. Seam-level verification: golden master, contracts, shadow diffing, reconciliation (depends on: 2, 3)
Replaces the impossible goal of blanket test coverage with verification exactly where the cut will be made. A two-million-line monolith cannot reach 70% coverage in a year; a service boundary can be verified to a very high standard in weeks.
- Build a characterization harness that records real production requests and replays them against the monolith, capturing full responses as a golden master. This is the safety net for every extraction.
- Require every extracted service to pass the golden master on its public API before it takes live traffic, producing a diff report rather than a pass/fail.
- Use consumer-driven contract tests between the monolith and each new service, and between services, so a change on one side breaks a build instead of production.
- Run shadow traffic: mirror live requests to the new service, compare responses field by field, and gate the traffic ramp on the divergence rate.
- Build per-module data reconciliation as a first-class test: row counts, checksums and business invariants compared on a schedule, with an owner and an alert threshold.
- Add synthetic canary transactions that execute a real checkout, return and search every few minutes and alert on functional regression before customers notice.
- Explicitly do not pursue blanket line coverage of the monolith. Track coverage only for newly written service code, where the target is 80%.
7. Data platform: schema ownership, join elimination, CDC, outbox, four-stage cutover playbook (depends on: 2, 3, 6)
The hardest part of the program and the part most plans under-specify. It does not depend on service extraction, so it starts in month one and runs in parallel with everything else.
- Enforce ownership inside the database itself: one PostgreSQL role per module, able to write only its own schema and to read others only through defined views. Cross-schema writes are rejected by the database, not by convention.
- Inventory every stored procedure, attribute it to one module, and either move it into that module's code or leave it as a module-private function. After a module is extracted, no stored procedure may touch two modules' tables.
- Eliminate cross-module joins one at a time, replacing each with an API call, an event-fed materialized read model or a duplicated read-only projection. Track the count per module and drive it to zero before that module is cut.
- Stand up change data capture with Debezium reading the PostgreSQL WAL into Kafka. This publishes monolith domain events with no application change, the lowest-risk start available.
- Add a transactional outbox for new services so their events and their state changes commit together.
- Adopt one reusable four-stage cutover playbook per module and apply it identically every time. Stage A: the service owns its schema logically, reads from CDC into its own store, and serves shadow traffic only. Stage B: reads cut over, the monolith stays system of record. Stage C: writes cut over, and the monolith's tables become read-only replicas fed by reverse CDC from the service. Stage D: old tables and dead code are dropped only after a full peak or four clean weeks, whichever is longer.
- Make stage C genuinely reversible: because the sync direction can be flipped, rolling back a write cutover is a configuration change plus a reconciliation pass, not a data restore.
- Build the reconciliation service now so every later cutover has an objective consistency check with thresholds and owners.
- Schedule the 1.2 TB storage migration as background work: new services start on the existing cluster with their own schemas, and physical split happens only once a module is stable.
8. Extract Catalog and Search (depends on: 5, 6, 7)
First extraction, chosen because it is read-heavy, mostly isolated and carries no transactional risk. It also pays for itself: replacing the nightly Lucene rebuild with real-time indexing is a visible business win that buys political cover for the harder cuts.
- Create a Catalog service owning product, category and media tables plus its own search index.
- Feed it from CDC so product and price changes appear in search within seconds instead of after a nightly rebuild.
- Route through the gateway behind a flag and ramp 1% → 5% → 25% → 50% → 100%, with the rollback controller able to revert to the monolith's internal Lucene path at any point.
- Run shadow traffic and compare result sets before any live traffic, then keep the old index warm for two weeks after full cutover.
- Verify the mobile app, which hits the same endpoints, inside the same ramp; its behaviour is part of the go/no-go.
- Land this cut in an open delivery window and let it soak at least four weeks before the freeze.
9. Extract Returns as the first write-path and own-database proof (depends on: 5, 6, 7)
Second extraction and the first that owns writes and a database. Returns is chosen because it is off the peak-critical path, has modest coupling, and exercises the full four-stage playbook at low stakes.
- Build the Returns service with its own schema, consuming order and customer events rather than joining their tables.
- Run the playbook end to end: shadow reads, read cutover, then write cutover with reverse CDC keeping the monolith's tables current.
- Prove the rollback path in a game day before write cutover, including a reconciliation pass and a re-run of the golden master.
- Keep the back-office returns screens on the monolith for now, so staff workflow is untouched by this step.
- Record every friction point and correct the playbook. The real output of this step is a proven, reusable procedure, not just one service.
10. Extract Inventory and replace the 15-minute warehouse file exchange (depends on: 5, 6, 7)
Removes one of the sharpest coupling points in the system and unblocks the checkout work. Inventory is extracted in parallel with the other early cuts because it couples the monolith to an external warehouse process rather than to other modules.
- Build the Inventory service to ingest the warehouse feed directly and publish stock-level events.
- Preserve the existing file-based interface for the first weeks, running the new ingest in parallel with the legacy feed and reconciling hourly until they agree.
- Keep the monolith's inventory tables as a projection fed by events, so cart and checkout keep working unchanged during the cut.
- Design reservation semantics now — reserve, confirm, release, with expiry — even though checkout is not yet extracted. The API is needed later and is cheap to get right here.
- Load-test inventory ingest at 12x, because the warehouse feed schedule and the sales peaks do not always coincide.
- Cut over reads first, then writes, with the rollback controller able to restore the file feed as the source of truth.
11. Extract Customer Accounts and Loyalty, with a conservative auth strategy (depends on: 5, 6, 7, 9)
Extracts customer accounts and loyalty, including the authentication decision. Auth is the step that most often derails e-commerce migrations, so the auth path is deliberately moved last and guarded hardest.
- Build the Customer service owning profile, address and loyalty tables, with country-specific loyalty rules expressed as data where possible and as code where not.
- Keep authentication in the monolith for the first phase. Move token issuance only once customer data is stable, and never within four weeks of a freeze.
- Introduce distributed session handling and a token-validation API so services can verify identity without querying the monolith database.
- Cut over reads, then writes, with reverse CDC, validating against the golden master across all 8 countries and 4 languages.
- Verify the mobile app's session behaviour explicitly, since it holds long-lived sessions the storefront does not.
- Move loyalty point accrual and redemption last, because a loyalty error is a customer-visible financial error, not a technical incident.
12. Extract Cart (depends on: 8, 10, 11)
Extracts the cart, which is stateful and sits directly in front of checkout. It is done before pricing and checkout because both need a stable cart boundary to call.
- Build the Cart service on Redis for session and line-item state, validating products and inventory through service calls rather than database joins.
- Make every cart operation idempotent, because a retried add or remove during a peak must not duplicate a line item.
- Keep the cart tables in the monolith as a read-only projection fed by events, for rollback and for the not-yet-migrated back-office screens.
- Ramp traffic while monitoring cart abandonment rate as the business metric, since cart latency shows up as lost revenue rather than as errors.
- Exercise anonymous and authenticated carts separately; they follow different paths and fail in different ways.
- Land this cut in an open window with a full four-week soak before the freeze.
13. Extract Pricing and Promotions as an unchanged black box (depends on: 5, 6, 7)
Extracts the 200,000-line pricing module without rewriting it. The rules are not understood by anyone, so they are wrapped and characterized rather than reverse-engineered. Rule decomposition, documentation and a DSL are explicitly out of scope for these twelve months.
- Build a golden master corpus from at least a million real historical pricing requests and their recorded outputs, covering all 8 countries, 3 currencies and 4 languages, plus every promotion type that can be discovered.
- Refactor only the module's dependencies: pricing must obtain customer, product and inventory data through interfaces rather than direct database access, so it can be lifted out.
- Move the pricing code into its own service unchanged, owning its tables after cutover, and expose a single decision API.
- Run it in shadow mode for at least four weeks against live traffic, comparing every computed price with the monolith. Any divergence blocks the ramp.
- Cut over behind a flag with per-country ramps, since a pricing error is a financial and legal exposure rather than a technical incident.
- Keep the in-monolith evaluator available and warm as the rollback path for at least one full peak after cutover.
- State in writing that rule decomposition is deferred to a follow-up program, so it does not creep back into this one.
14. Extract Payment under a stricter regime than anything else (depends on: 5, 6, 7)
Extracts payment processing, where mistakes are irreversible and regulatory. Payment is done before checkout orchestration, because checkout cannot be decomposed without a payment boundary already in place.
- Build the Payment service owning the integration with the three providers, including tokenization, authorisation, capture, refund and provider webhooks.
- Reduce PCI scope rather than expand it: no raw card data at rest in the new service, credentials in secrets management, no card data in logs or traces.
- Make every payment operation idempotent with explicit idempotency keys, because retries at peak are normal and double charges are not recoverable.
- Cut over provider by provider rather than all three at once, starting with the lowest-volume provider.
- Run the golden master across all decline, timeout, partial-authorisation and refund scenarios, and rehearse the fallback to the monolith's direct provider integration.
- Verify fraud detection and 3-D Secure paths explicitly, since they are usually the least covered and the most visible when they break.
- Land this cut early in an open window so it soaks well before the freeze.
15. Extract Order Management with an explicit state machine (depends on: 9, 10, 13, 14)
Extracts order management as the record of truth for the order lifecycle, after the services it depends on exist and are stable.
- Build the Order service with its own database and an explicit order state machine that validates every transition.
- Introduce event sourcing for order status so the audit trail satisfies regulators and fulfilment teams, and so state can be rebuilt after an incident.
- Consume events from payment, inventory and returns rather than polling or joining.
- Cut over reads first for the five teams that query orders, then writes, keeping the monolith's order tables as a reverse-CDC projection.
- Reconcile order counts and monetary totals hourly against the monolith throughout the transition. A monetary mismatch is an immediate rollback, not a ticket.
- Load-test concurrent order state transitions at peak, since the state machine becomes the new serialisation point.
16. Compose Checkout from independent services using a saga (depends on: 12, 13, 14, 15)
The highest-risk cut in the program, deliberately placed last among the transactional work and only after the components it orchestrates are individually proven.
- Build an orchestrating Checkout service that performs: cart validation, price computation, inventory reservation, payment authorisation, order creation.
- Implement compensating actions for every step: a failed authorisation releases the inventory reservation; a failed order creation voids the authorisation.
- Require idempotency keys end to end so a retried checkout cannot double-charge or double-reserve.
- Handle timeouts explicitly, including the peak case where inventory or pricing is slow. The saga must fail safe to a retryable state, never to a half-committed order.
- Mirror live checkout traffic to the new orchestration and compare full outcomes, including order totals and reservations, before any live traffic.
- Ramp live traffic during an open window only, and keep the monolith's checkout path fully functional and warm for rollback until it has survived a peak.
- Hold the six-week peak-readiness gate before this ramp and treat a failed gate as a stop, not a delay.
17. Migrate back-office, storefront and mobile clients off the monolith database (depends on: 16)
Moves the clients and the 300 back-office users onto the service APIs. Until this happens, the monolith's database remains a dependency even where the logic has already moved.
- Refactor back-office screens to consume service APIs through the gateway, replacing direct SQL access table by table, starting with orders and customers.
- Add aggregation endpoints where a screen needs several services, plus a short-lived cache so 300 staff do not multiply load on the new services.
- Update the server-rendered storefront to call service APIs while keeping the existing rendering path working behind a flag, so a rendering regression is a flag flip rather than a rollback.
- Point the mobile app at the gateway for migrated endpoints while keeping the old endpoints alive for un-updated app versions, since users do not upgrade on your schedule.
- Publish API versioning rules and deprecation windows so teams can change their services without coordinating with client releases.
- Load-test back-office behaviour with 300 concurrent staff on top of peak storefront traffic, since the two now share services.
18. Decommission the monolith core and harden for the second peak (depends on: 17)
Removes what is left of the monolith and proves the new architecture survives a peak. This step is as much about proving the state is coherent as about deleting code.
- Delete dead code and dropped tables module by module, only after a module has run a full peak or four clean weeks, whichever is longer.
- Keep read-only access to the old database for a defined period for historical and regulatory queries, then archive and decommission it.
- Replace the monolith's remaining cross-module reads with service calls or event-fed projections. The monolith should now be a small set of modules, or nothing at all.
- Re-run the full 12x load test against the new topology across all 8 countries, 3 currencies and 4 languages, and tune autoscaling, connection pools and broker partitions from the results.
- Run chaos game days: kill each service in turn and confirm the storefront degrades gracefully rather than failing completely.
- Confirm the peak-readiness gate before the second peak and publish its evidence. A failed gate defers remaining work rather than risking the peak.
- Write the exit report: final service boundaries, data ownership, runbooks, SLO history, the scope-ladder rung actually reached, and the list of work explicitly deferred to a follow-up program.
Previous Proposal 3 (ID: 10bf57da-bf5a-4286-93d2-7a544776a748, Agent: qwen3.8-flash_refine_3, LLM: alibaba/qwen3.8-flash):
Estimated Complexity: high
Success Metrics: - **Zero Downtime**: 100% availability maintained throughout the 12-month migration, excluding planned maintenance windows.
- **Rollback Speed**: Every service deployment is reversible in < 10 minutes via automated traffic switching at the Gateway.
- **Peak Performance**: The new architecture sustains 12x baseline load (480k orders/day) with < 200ms P95 latency for Checkout.
- **Data Integrity**: Zero discrepancies between pricing calculations of the old monolith and the new Pricing Service across 1 million replayed requests.
- **Independence**: Teams successfully deploy their services on a weekly cadence without coordinating with the monolith's bi-weekly release.
Steps (12):
1. Mobilization and Strategic Freeze Planning
Establish the governance and safety constraints for the migration. This step defines the 'no-touch' windows around peak seasons (January and July) and sets up the steering committee to manage the complexity of a 2M LOC codebase.
- **Team Alignment**: Reorganize the 5 teams into 'Service-First' pods. Each pod owns a target service extraction alongside their monolith maintenance duties.
- **Risk Framework**: Define strict 'Freeze Windows' (e.g., Dec 15–Jan 15, June 15–July 15) where no architectural changes are permitted, only bug fixes.
- **Dependency Mapping**: Create a 'Coupling Heatmap' identifying the most entangled modules (likely Pricing and Checkout) to isolate them for later phases.
2. Target Architecture and Domain Boundaries (depends on: 1)
Perform rigorous Domain-Driven Design (DDD) to define service boundaries. Given the 2M LOC and 350 tables, abstracting the domain is critical to prevent 'distributed monolith' outcomes.
- **Strategic DDD**: Map current modules to bounded contexts (Catalogue, Pricing, Orders, Identity, Fulfillment).
- **Database Decomposition Design**: Define the target data model for each service. Explicitly list which of the 350 tables move to which service and which cross-module joins must be replaced by API calls or events.
- **Contract Definition**: Draft API contracts (OpenAPI/GraphQL) for the core services to ensure backward compatibility with the existing frontend.
3. Core Infrastructure and Observability Foundation (depends on: 1)
Build the 'platform' that allows services to exist independently. You cannot safely extract services without first having the tools to see, test, and deploy them individually.
- **Kubernetes Cluster**: Provision a production-grade K8s environment with strict namespace isolation.
- **API Gateway**: Deploy a robust API Gateway (e.g., Kong, AWS ALB) to sit in front of the monolith. This is the 'Traffic Switcher' for the Strangler Fig pattern.
- **Observability Stack**: Implement Distributed Tracing (Jaeger), Centralized Logging (ELK/Loki), and Metrics (Prometheus). You must be able to trace a request from the gateway through a new service and back to the monolith.
- **CI/CD Pipelines**: Create independent deployment pipelines for services, allowing 15-minute rollback capabilities distinct from the monolith's 2-week cycle.
4. Test Harness: 'Golden Master' Characterization (depends on: 3)
Since testing the new logic against the old logic is the primary validation method, create an automated regression suite that captures the 'current truth' of the legacy system.
- **Input Logging**: Configure the monolith to log all incoming requests (and their responses) to a secure data lake, anonymizing PII.
- **Replay Engine**: Build a tool that takes a captured legacy request, sends it to both the legacy monolith and the new service, and diffs the responses.
- **Coverage Baseline**: Establish a 100% test coverage requirement for the *interfaces* being extracted. If you extract 'Search', you must have a test for every possible search query variant currently supported.
5. Extraction 1: Catalogue and Read-Only Search (depends on: 4)
The 'Low Hanging Fruit'. Extract the read-only Catalogue and Search capabilities first. This builds confidence and proves the Strangler Fig pattern without touching transactional data.
- **New Service**: Build 'Catalogue Service' that reads from a replicated Postgres (via logical replication) or a dedicated search DB (Elasticsearch).
- **Traffic Shift**: Configure the API Gateway to route `/products` and `/search` requests to the new service.
- **Fallback**: If the service fails, the gateway should immediately reroute to the legacy monolith (circuit breaker).
- **Optimization**: Replace the nightly Lucene rebuild with real-time indexing to instantly reflect price/inventory changes.
6. Extraction 2: Customer Identity and Profile (depends on: 5)
Extract user data handling. This decouples the 'who' from the 'what' (purchases), allowing independent authentication scaling.
- **Account Service**: Move user tables (Login, Profile, Address) to a dedicated service.
- **Session Migration**: Implement a token-passing strategy where the legacy monolith trusts tokens generated by the new Identity Service.
- **Read-Through Cache**: The legacy monolith should stop querying the user table directly; instead, it fetches user details from the Identity Service via an internal REST call or cached event.
- **Rollback**: Keep a 'sync-back' script to ensure if users are created in the new service, the legacy DB knows about them during the transition period.
7. Database Decoupling: The 'Anti-Corruption' Layer (depends on: 3, 5)
The most dangerous step. Breaking the 1.2TB DB entanglement requires intercepting the stored procedures. We stop writing to the shared DB from new services.
- **CDC Implementation**: Deploy Debezium to capture Postgres Write-Ahead Logs (WAL) into Kafka. This allows new services to be notified when the monolith updates data.
- **Outbox Pattern**: Refactor the monolith code so that when it writes to the DB, it also writes a 'domain event' to an internal Outbox table, which Debezium then publishes.
- **Read-Only Replicas**: Force new services to read from read-only replicas of the legacy DB to prevent them from causing lock contention on the master.
8. Extraction 3: Inventory and Fulfillment Interface (depends on: 7)
Move the inventory logic out. This separates the 'Stock' truth from the 'Order' truth, preparing for the complex checkout.
- **Inventory Service**: Create a service to hold the 'Single Source of Truth' for current stock levels.
- **Legacy Integration**: The monolith's checkout flow must now ask the Inventory Service to 'Reserve Stock' before processing payment.
- **Warehouse Sync**: Move the 15-minute file exchange logic into this service, isolating the legacy code from warehouse connectivity issues.
- **Concurrency Handling**: Implement optimistic locking in this service to handle high-concurrency 'reserve' requests during sales.
9. Extraction 4: Pricing and Promotions (The 'Black Box') (depends on: 8)
Extract the 200,000 LOC pricing engine. Do not rewrite the logic yet; wrap it. This is a 'Strangler Fig' step, not a refactoring step.
- **Encapsulation**: Move the existing pricing code (and its dependencies) into a new Spring Boot project called 'Pricing Service'.
- **Dependency Injection**: Replace direct DB access within the pricing logic with interfaces that call the Catalogue and Customer services via API.
- **Performance Parity**: Ensure the latency added by moving pricing to a separate network call is negligible (<50ms). Cache aggressively at the service level.
- **Validation**: Use the Golden Master (S4) to replay all historical orders and verify the new service returns the exact same price down to the cent.
10. Extraction 5: Checkout Orchestrator (Saga Pattern) (depends on: 9)
Replace the monolithic transaction with a distributed saga. This is the final piece of the transactional flow.
- **Orchestrator**: Build a lightweight service that coordinates the 'Checkout' process.
- **Saga Logic**: When an order is placed: 1. Call Pricing Service. 2. Call Inventory Service (Reserve). 3. Call Payment Gateway (External). 4. Call Order Service (Create).
- **Compensation**: If step 4 fails, the Orchestrator triggers 'Cancel Reserve' on the Inventory Service and 'Void' on the Payment Gateway.
- **Legacy Cutoff**: The monolith's 'Checkout' screen is replaced by a frontend form that calls this Orchestrator API.
11. Final Monolith Decomposition and Clean-up (depends on: 10)
At this stage, the monolith is hollowed out, containing mostly code that is called by the new services or legacy admin functions.
- **Admin Panel**: Move back-office functionality (Order management, Refunds) into a 'Management Service' that reads from the new event streams.
- **Code Deletion**: Delete the code for the extracted domains (Pricing, Search, Cart) from the monolith repository to enforce boundaries.
- **Database Cleanup**: Drop the tables owned by new services from the legacy monolith database.
- **Performance Tuning**: Optimize the remaining monolith for the only things it does: serving legacy redirects and perhaps a few 'orphaned' modules.
12. Peak Season Stress Test and Handover (depends on: 11)
Prepare for the high-volume events in Jan/July. Validate the new architecture holds under pressure.
- **Chaos Engineering**: Randomly kill the Search or Inventory services and verify the site degrades gracefully (e.g., 'Search temporarily unavailable') without crashing the checkout.
- **Load Testing**: Simulate 12x peak traffic using tools like Gatling/JMeter against the new APIs.
- **Runbooks**: Finalize operational playbooks for every team. Who owns what? How to restart a dead service? How to fallback to the monolith if the database fails?
Please, considering the previous proposals as ideas that could be considered, focus on the main objective and generate an IMPROVED proposal or a completely DIFFERENT perspective if you deem it appropriate. Only if you consider any of them is amazing and impossible to improve, answer with the same proposal.
The plan has these parts:
- "steps": the list of steps, each with "step_id" (a short label unique within this proposal, such as S1, S2, S3), "title" (a short, descriptive title), "description" (what the step does and how, in Markdown: a short opening paragraph and then, if there are several concrete things to say, a bullet list) and "dependencies" (the step_ids of the other steps of THIS proposal that must be completed first; empty if none).
- "estimated_complexity": "low", "medium" or "high".
- "success_metrics": clear and measurable success metrics, one per line as a bullet list.
Think deeply about the problem, considering all aspects and implications. Develop a comprehensive understanding of what needs to be done to achieve the objective, then produce the plan.
{"steps": [{"step_id": "S1", "title": "Program Setup, Scope Ladder, Organizational Model, and Peak-Safe Calendar", "description": "Establishes the governance framework and constraints that all later work obeys. The calendar is the binding constraint—January and July peaks must not be put at risk—so it is decided first, before any technical choices.\n\n**Inception and Baselines**: Run a two-week inception to establish current state: build time, deployment lead time, change failure rate, MTTR per team, module-change frequency, database load profiles (all measurable, not asserted).\n\n**Calendar and Freeze Windows**: Declare hard freezes from December 1–January 15 and June 1–July 15; only rollback-enabling and hardening changes allowed during freezes. Confirm two open delivery windows per year (February–May and August–November); all migration work must fit these windows. No change on checkout path lands within four weeks of a freeze.\n\n**Scope Ladder**: Define ranked rungs 1–6 that deliver the core objective; rungs 7+ are optional. Slippage means stopping at a rung boundary, never mid-increment. Rungs: 1. Platform ready. 2. Search extracted and proven. 3. Returns and Inventory proven at low stakes. 4. Payment and Orders stable. 5. Checkout orchestration live and soaking. 6. Back-office migrated, monolith core reduced.\n\n**Organizational Model**: Define service-aligned teams (Search, Orders, Inventory, Payments, Customer, Fulfillment) with clear ownership, on-call rotations, and SLOs per service. Each team owns codebase, pipeline, database schema, and incidents by month 6. Transition plan: teams split duties (monolith maintenance + service) until month 3, then shift to service-primary by month 6.\n\n**Rollback Charter**: Every increment ships an expand/contract database change, a feature-flag kill switch, and a recorded game-day rehearsal. No go-live without tested rollback in < 30 minutes.\n\n**Peak-Readiness Gate**: Define gate to run six weeks before each peak (mid-November, mid-May): 12x load test, capacity headroom check, rollback rehearsal, error-budget review. Gate is pass/fail; failed gate defers work to next window.\n\n**Capacity Budget**: Allocate 40–50% of five teams' capacity for migration; staff scope ladder to fit capacity, not to fill the year. Create migration enablement squad of six rotating engineers to own platform, shared cuts, and risky data work.", "dependencies": []}, {"step_id": "S2", "title": "Executable Architecture Map, Table Ownership, and Boundary Enforcement", "description": "Produces an architecture map that the build itself enforces. Five teams in one repo will silently re-couple anything separated if not policed, so enforcement is embedded in the map.\n\n**Real Coupling via Tracing**: Instrument monolith with distributed tracing; let it run four weeks to capture real call paths—static imports miss true coupling.\n\n**Table Ownership Matrix**: Parse every SQL statement, ORM mapping, and stored procedure; cross-check against database query logs. Build table-to-module and query-to-module map. Assign every 350 table to exactly one owning module; tables nobody can own are 'contested' and scheduled into data work (Step 7).\n\n**Scoring and Extraction Sequence**: Score each candidate service on coupling, transactional risk, change frequency, and peak-path criticality. This ranking (not intuition) drives extraction order.\n\n**Enforcement via Automation**: Add ArchUnit rules to CI to fail builds on new cross-module Java dependencies (existing violations frozen in baseline that may only shrink). Add SQL linter to CI to fail on cross-module joins and cross-module writes (same shrinking baseline). Violations tracked weekly in architecture review.\n\n**Stored Procedure Audit**: Inventory all stored procedures; attribute to owning module; plan move into module code or leave as module-private function. No stored procedure may touch two modules' tables post-extraction.\n\n**Architecture Decision Records**: Publish target service list, owning team per service, and reasoning as ADRs.\n\n**Mid-Program Review**: Hold review at month 6 to re-rank scope ladder using what the map actually revealed. This is the one planned re-planning point of the program.", "dependencies": ["S1"]}, {"step_id": "S3", "title": "Delivery Platform: Per-Service Pipelines, Gateway, Feature Flags, and Environments", "description": "Builds the delivery and traffic machinery that makes every later step reversible. No service is extracted until its team can deploy, flag, and route independently.\n\n**Kubernetes and Namespaces**: Extend platform on Kubernetes (or existing container platform) with one namespace per service, quotas, and autoscaling sized for 12x peak (480k orders/day). Establish dev/staging/prod with strict resource isolation.\n\n**API Gateway**: Deploy API gateway (Kong, AWS ALB) in front of monolith as strangler entry point. Storefront, mobile app, and back-office traffic flow through gateway from day one, even while routing everything to monolith. Gateway enforces rate limiting, bulkheads, timeouts, and circuit breakers.\n\n**Feature-Flag Service**: Deploy centralized feature-flag system (LaunchDarkly, Unleash). Require every new call path to be flag-guarded. Flags are the primary rollback instrument; changes to traffic routing require no code deployment.\n\n**Per-Module CI/CD Pipeline**: Give every module its own independent CI/CD pipeline and environment. Monolith keeps current pipeline for hotfixes until Step 5 replaces it. Pipeline includes automated security scanning, performance baselines, and contract-test gates.\n\n**Secrets and Configuration**: Introduce secrets management (Vault) and per-environment configuration. Behavioral changes require no monolith redeploy.\n\n**Golden-Path Templates**: Define reusable templates for new services: build layout, Dockerfile, pipeline stages, observability instrumentation, health checks, feature-flag integration, database migration tool. Extraction starts from template, not blank page.\n\n**Permanent Environments**: Reserve two full-size environments: (1) production-like soak environment for multi-week stability validation, (2) load-test environment capable of 12x traffic generation against production-shaped data (8 countries, 3 currencies, 4 languages, realistic product catalog).", "dependencies": ["S1", "S2"]}, {"step_id": "S4", "title": "Observability, Business SLOs, Error Budgets, and Automated Rollback Controller", "description": "Makes the system observable so canaries are judged automatically and reverted without human guessing. This is the prerequisite for rollback promises in all later steps.\n\n**Observability Foundation**: Deploy centralized logging (ELK/Loki), metrics (Prometheus/Grafana), and distributed tracing (Jaeger) with trace correlation working across gateway, monolith, and every new service from day one.\n\n**Blind-Spot Instrumentation**: Instrument monolith's unmeasured aspects: query latency by module, connection-pool saturation, Lucene rebuild duration, warehouse file-exchange lag, stored procedure execution time, lock contention.\n\n**Business SLOs**: Define SLOs on business outcomes, not infrastructure:\n- Checkout success rate ≥ 99.5%\n- Order confirmation latency p99 ≤ 5 seconds at baseline (40k orders/day) and peak (480k orders/day)\n- Search result latency p95 ≤ 1 second\n- Payment authorization latency ≤ 2 seconds\n- Price computation latency ≤ 200 ms\n- Warehouse sync freshness ≤ 2 minutes end-to-end (vs. current 15 minutes)\n- Cross-module data consistency: hourly reconciliation shows < 0.001% row-count discrepancy\n\n**Error Budget and Rollback Policy**: Attach error budget to each SLO. When a service burns budget (or latency diverges > threshold during canary), its rollout stops automatically and flags revert without negotiation. Document policy explicitly; use during peaks without exception.\n\n**Automated Rollback Controller**: Build system that monitors error rate and latency divergence during canary. On breach, gateway shifts traffic back and flags disable automatically. Fallback requires no human intervention. Test this automation in monthly game days.\n\n**Dashboards**: Create per-service dashboards readable by tired engineers at 3 AM (traffic, errors, latency p50/p95/p99, database load). Create program dashboard showing progress against scope ladder, rung by rung.", "dependencies": ["S3"]}, {"step_id": "S5", "title": "Pricing Module: Rules Catalog and Golden-Master Characterization (Parallel with Data Platform)", "description": "Catalog the 200k LOC pricing engine behavior before any extraction attempt. This is the foundational risk mitigation for the most complex module; it runs in parallel with data platform work (Step 7) because it is independent of infrastructure.\n\n**Rules Discovery and Documentation**: Analyze and document all pricing rules in scope: country-specific logic (8 countries), currency handling (3 currencies), promotional rules, seasonal pricing, bulk discounts, loyalty point applications, regional variations. Create a living rules inventory.\n\n**Historical Request Corpus**: Capture at least 1 million real historical pricing requests from production logs, covering all 8 countries, 3 currencies, 4 languages, all promotion types discoverable, edge cases, peak-season variations. Record exact inputs and outputs.\n\n**Golden-Master Characterization Suite**: Build automated harness to replay corpus against monolith, capturing deterministic responses. This suite is the 'golden master': any new pricing service must match 100% of outputs. Suite becomes the automated gate for pricing extraction (Step 14).\n\n**Test Data Expansion**: Supplement historical data with synthetic edge cases: multi-currency conversions, minimum purchase thresholds, conflicting promotions, time-based seasonal rules, inventory-driven pricing, customer-segment overrides.\n\n**Dependency Mapping**: Explicitly document which customer attributes, product attributes, inventory levels, time-based factors, and external parameters affect pricing. Identify all cross-module dependencies that pricing currently reads from monolith (e.g., customer loyalty status from Customer module, product hierarchy from Catalogue module).\n\n**Baseline Validation**: Run golden master against monolith to establish baseline passing rate. Document any non-deterministic behavior or race conditions found. This baseline is locked; no drift allowed during migration.\n\n**CI Gate Definition**: Define hard rule: pricing service extraction cannot proceed until characterization tests pass 100% against both monolith and new service. Any divergence blocks ramp. This gate is not negotiable.", "dependencies": ["S1", "S2"]}, {"step_id": "S6", "title": "Seam-Level Verification: Golden Master, Contracts, Shadow Diffing, and Reconciliation", "description": "Replaces impossible goal of blanket test coverage with verification exactly at the cut point. A 2M-line monolith cannot reach 70% coverage in a year; a service boundary can be verified to very high standard in weeks.\n\n**Characterization Harness for All Services**: Build framework to record real production requests (anonymizing PII) and replay against monolith. Capture full responses as golden master. Every extracted service must pass golden master on its public API before taking live traffic. Output a diff report, not pass/fail.\n\n**Consumer-Driven Contracts (Pact)**: Require contracts between monolith and each new service, and between services themselves. A change on one side breaks a build instead of waiting for production. Contracts versioned; breaking changes trigger explicit communication plan.\n\n**Shadow Traffic and Response Diffing**: Mirror live requests to new service; compare responses field by field (not just status codes). Measure divergence rate continuously. Gate traffic ramp on divergence < 0.01% for 48 hours.\n\n**Per-Module Data Reconciliation**: Build data reconciliation as first-class test, not afterthought. Compare row counts, checksums, and business invariants on hourly schedule. Owner assigned; alert threshold set. Reconciliation runs continuously during transition period (Stages A–C of cutover playbook).\n\n**Synthetic Canary Transactions**: Implement real checkout, return, and search transactions executing every few minutes. Alert on functional regression before customers notice. Include multi-country, multi-currency variations.\n\n**Explicit Non-Goal**: Do not pursue blanket line coverage of monolith. Track coverage only for newly written service code, target 80%. Seam-level verification replaces this impossible goal.", "dependencies": ["S2", "S3"]}, {"step_id": "S7", "title": "Data Platform: Schema Ownership, Join Elimination, CDC, Transactional Outbox, and Four-Stage Cutover Playbook", "description": "The hardest and most under-specified part of most migrations. This work is independent of service extraction, so it starts in month 1 and runs in parallel. It is the foundation for reversible data transitions.\n\n**Database-Enforced Ownership**: Assign every PostgreSQL table to exactly one module. Create one role per module, able to write only its own schema and to read others only through defined views. Database rejects cross-schema writes at the engine level, not by convention. Test this enforcement in CI.\n\n**Stored Procedure Refactoring**: Inventory every stored procedure, attribute it to owning module. Either move logic into that module's application code or leave as module-private database function. After extraction, no stored procedure may touch two modules' tables.\n\n**Cross-Module Join Elimination**: Eliminate cross-module joins one at a time, replacing each with an API call (preferred during cutover), an event-fed materialized read model, or a duplicated read-only projection. Track count per module; drive to zero before that module is extracted.\n\n**Change Data Capture (CDC)**: Deploy Debezium reading PostgreSQL WAL into Kafka. This publishes monolith domain events with zero application change—lowest-risk start possible. Configure per-table CDC; test at peak load (480k events/day during 12x peak).\n\n**Transactional Outbox Pattern**: For all new services, add outbox table. When service writes business state, it writes domain event atomically in same transaction. Outbox relay publishes to Kafka, ensuring no event loss. Implement poison-pill handling for failed publishes.\n\n**Four-Stage Cutover Playbook (Reusable)**: Define one playbook applied identically every service extraction:\n- **Stage A** (Shadow-Read): Service owns schema logically, reads from CDC into its own store, serves shadow traffic only. Monolith remains system of record; no cutover yet.\n- **Stage B** (Read Cutover): Reads cut over to new service via flag. Monolith stays system of record via reverse-CDC replication. Rollback is flag flip + reconciliation pass.\n- **Stage C** (Write Cutover): Writes cut over to new service. Monolith tables become read-only replicas fed by reverse CDC from service. Rollback is configuration change (flip sync direction) + reconciliation, not data restore.\n- **Stage D** (Deletion): Old tables and dead code dropped only after module has survived one full peak (January or July) or four clean weeks, whichever is longer. Maintain 90-day read-only archive of old tables for regulatory retention and emergency queries.\n\n**Reconciliation Service**: Build now (not later) so every cutover has objective consistency check. Compare row counts, business-invariant checksums, monetary totals hourly. Owner assigned; thresholds set. Mismatch is immediate rollback signal.\n\n**Storage Migration Timeline**: New services start on existing cluster with own schemas. Physical database split (move to separate cluster) happens only once module is stable and proven at peak. This removes a critical-path blocker and allows parallelization.", "dependencies": ["S2", "S3"]}, {"step_id": "S8", "title": "Extract Catalogue and Search: Read-Heavy Pilot Service", "description": "First extraction, chosen because it is read-heavy, isolated, and carries no transactional risk. It also pays for itself: replacing nightly Lucene rebuild with real-time indexing is a visible business win that buys political cover for harder cuts.\n\n**New Catalogue Service**: Create service owning product, category, media, and attributes tables. Build search API using Elasticsearch/OpenSearch with real-time indexing.\n\n**CDC Feed**: Subscribe to CDC stream from monolith. ProductUpdated, PriceChanged, InventoryUpdated events trigger real-time search index refresh. Product availability reflects in search within < 60 seconds of change (vs. nightly rebuild).\n\n**Shadow Traffic and Diff Validation**: Route requests through gateway behind feature flag. Run shadow mode: send requests to both monolith Lucene and new Search service; compare result sets field by field. Measure divergence; require < 0.01% for 48 hours before traffic ramp.\n\n**Gradual Traffic Ramp**: 1% → 5% → 25% → 50% → 100% using feature flags and canary deployments. Rollback controller monitors latency and error rates; reverts flag if breach. Keep old Lucene index warm for two weeks post-cutover as rollback target.\n\n**Mobile App Verification**: Verify mobile app behavior explicitly; it hits same endpoints. Test session persistence, offline search cache behavior, and app version compatibility during ramp.\n\n**Four-Stage Playbook**: Execute Stages A–D as defined in Step 7. Stage A (shadow) lasts 1 week minimum. Stage B (read cutover) lasts 2 weeks. Stage C does not apply (reads only). Stage D (cleanup) after one peak or four weeks.\n\n**Soak Period**: Land this extraction in open delivery window; soak at least four weeks before freeze (Dec 1 or June 1). No extraction reaches production less than four weeks before a freeze.", "dependencies": ["S5", "S6", "S7"]}, {"step_id": "S9", "title": "Extract Returns: Low-Stakes Proof of Four-Stage Playbook", "description": "Second extraction and first write-path proof. Returns is chosen because it is off peak-critical path, has modest coupling, and exercises full four-stage playbook at low risk. Primary output is a proven, reusable procedure, not just one service.\n\n**Returns Service**: Build with own schema. Consume order and customer events rather than joining their tables. Implement return state machine: Requested → Approved → Shipped → Received → Refunded.\n\n**Full Four-Stage Execution**: Apply Stages A–D end-to-end with explicit recorded game day validating each stage rollback path. Stage A (shadow reads) for 1 week. Stage B (read cutover) for 2 weeks. Stage C (write cutover) with reverse CDC. Stage D (cleanup) after one peak or four weeks.\n\n**Rollback Rehearsal**: Before write cutover, execute full game day: simulate service failure mid-cutover, trigger rollback (reverse CDC, flag flip, reconciliation), verify all data consistent, re-run golden master, confirm back-office queries still work. Record this session; play back monthly.\n\n**Back-Office Screens**: Keep back-office returns screens on monolith for now (staff workflow untouched). Returns service is API-only; back-office integration comes later (Step 18).\n\n**Friction Point Capture**: Record every operational friction, process gap, and test hole discovered during extraction. Update playbook from learnings. This step is as much about process validation as about extracting Returns.\n\n**Soak and Timing**: Execute in open window; soak returns service for minimum four weeks before any freeze. Gate to proceeding to Inventory (Step 10) is successful four-week soak with zero rollbacks and full reconciliation agreement.", "dependencies": ["S5", "S6", "S7"]}, {"step_id": "S10", "title": "Extract Inventory: Warehouse Sync Improvement and Reservation Semantics", "description": "Removes one of sharpest coupling points (15-minute file-exchange lag) and unblocks checkout work. Inventory runs in parallel with returns because it couples monolith to external warehouse system, not to other modules.\n\n**Inventory Service**: Ingest warehouse feed directly (SFTP/API) instead of monolith polling. Design reservation semantics now: Reserve (place hold), Confirm (finalize after order), Release (cancel reservation on timeout/failure), with explicit timeout windows. Own stock levels and reservations per product per location.\n\n**Parallel Feeds During Transition**: Run new ingest in parallel with legacy 15-minute feed. Reconcile hourly until both agree. This validates the new ingest does not miss updates or duplicate changes.\n\n**Monolith Inventory Tables as Projection**: Keep monolith's inventory tables as read-only replicas fed by CDC from new service during Stage C (write cutover). Cart and checkout continue calling monolith queries unchanged during cutover; no checkout changes yet.\n\n**Four-Stage Execution**: Apply Stages A–D. Stage A (shadow ingests and reads) for 2 weeks (must survive two 15-minute sync windows and validate no drift). Stage B (read cutover) for 2 weeks. Stage C (write cutover) with reverse CDC. Stage D (cleanup) after one peak.\n\n**Peak-Load Testing**: Load-test inventory ingest at 12x (400k SKU updates/day during peak). Warehouse feed schedule and sales peaks do not always align; test worst-case concurrency. Validate no reservation deadlocks, no stock over-sells.\n\n**Cutover Order**: Inventory read cutover must complete before Cart extraction (Step 13) to avoid monolith checkout calling new Inventory service via internal API during transition.\n\n**Soak and Gate**: Soak minimum four weeks before freeze. Gate to proceeding to Customer (Step 11) is four-week soak with zero reconciliation mismatches and warehouse feed lag improved to < 2 minutes.", "dependencies": ["S5", "S6", "S7"]}, {"step_id": "S11", "title": "Extract Customer Accounts and Loyalty: Conservative Authentication Strategy", "description": "Extracts customer identity, profile, and loyalty programs. Authentication is deliberately placed late and guarded hardest because auth failures derail e-commerce migrations most often.\n\n**Customer Service**: Own profile, address, and loyalty tables. Implement country-specific loyalty rules (8 countries, different point accrual rates) as data-driven rules where possible, code where not. Design API: GetCustomer, UpdateProfile, GetLoyaltyBalance, RedeemPoints, AccruePoints.\n\n**Authentication Strategy Phase 1**: Keep authentication (login) in monolith for now. Customer service exposes only data APIs; token issuance remains monolith's responsibility. This delays risky auth cutover; less risk to peak season.\n\n**Distributed Session Handling**: Introduce Redis-backed distributed sessions. Services can verify customer identity without querying monolith database. Implement token-validation API so services can verify bearer tokens without round-tripping to monolith.\n\n**Data Cutover**: Execute four-stage playbook. Stage A (shadow reads) for 1 week. Stage B (read cutover) for 2 weeks. Stage C (write cutover) for new customers, address updates, loyalty accrual. Stage D (cleanup) after one peak.\n\n**Golden Master for All Countries**: Golden master captures customer queries across all 8 countries, all 4 languages, and all loyalty-rule variations. Shadow-traffic diff must show < 0.01% divergence before read cutover.\n\n**Mobile App Session Behavior**: Test mobile app's long-lived sessions explicitly; storefront does not hold sessions same way. Validate token refresh, session timeout, and app version compatibility during cutover.\n\n**Loyalty Accrual Last**: Move loyalty point accrual and redemption last within this step (Stage C final substep). Loyalty error is customer-visible financial error, not technical incident; guard hardest.\n\n**Soak and Gate**: Soak minimum four weeks. Gate to proceeding to Cart (Step 13) is successful loyalty accrual cutover with zero customer complaints and full reconciliation agreement.", "dependencies": ["S9", "S10"]}, {"step_id": "S12", "title": "Extract Cart: Stateful Session Service", "description": "Extract shopping cart, which is stateful and sits directly in front of checkout. Extracted before Pricing and Checkout because both depend on stable Cart boundary.\n\n**Cart Service on Redis**: Build on Redis (or PostgreSQL with session affinity) for session and line-item state. Validate products and inventory through service API calls rather than direct database joins. Design API: AddItem, RemoveItem, UpdateQuantity, GetCart, ApplyCoupon, ClearCart.\n\n**Idempotent Operations**: Every cart operation is idempotent. Retried add during peak does not duplicate line item. Retried remove is safe. Implement via unique constraint on (session, sku) or idempotency-key header.\n\n**Monolith Cart Tables as Projection**: Keep monolith's cart tables as read-only projections fed by CDC from Cart service. Back-office screens continue reading old cart tables for abandoned-cart analytics (not yet migrated to service APIs in this step).\n\n**Four-Stage Execution**: Apply Stages A–D. Stage A (shadow reads) for 1 week. Stage B (read cutover) for 2 weeks (use feature flag; gradual ramp 10% → 50% → 100%). Stage C (write cutover to service); Stage D after one peak.\n\n**Business Metric Monitoring**: Cart latency surfaces as lost revenue (abandonment), not just error logs. Track cart abandonment rate and add-to-cart latency as primary success metrics during ramp.\n\n**Anonymous vs. Authenticated Carts**: Test both paths separately; they follow different session-tracking mechanisms and fail in different ways. Ensure cart persists across login boundary.\n\n**Soak Before Freeze**: Land in open window; soak minimum four weeks before freeze (Dec 1 or June 1). Gate to proceeding to Pricing (Step 14) is four-week soak with cart abandonment rate unchanged or improved and zero lost transactions.", "dependencies": ["S6", "S7", "S10", "S11"]}, {"step_id": "S13", "title": "Extract Pricing as Black Box Using Golden-Master Validation", "description": "Extract 200k LOC pricing logic as-is without rewriting. Rules are not understood by anyone, so wrap and characterize rather than refactor. Rule decomposition deferred to follow-up program in writing.\n\n**Wrap Without Refactor**: Move pricing code into dedicated service, unchanged. Service owns pricing tables post-cutover. Expose single decision API: ComputePrice(customerId, productId, locationId, timestamp, quantityId, loyaltyStatus) → {price, applicablePromotions, taxes, currency}.\n\n**Dependency Injection for Reads**: Refactor pricing's dependencies so it obtains customer data via Customer service API, product data via Catalogue service API, inventory via Inventory service API. No direct cross-module database joins.\n\n**Golden-Master Validation**: Run characterization test suite (built in Step 5) against new service. Require 100% output match on all 1M historical requests across all 8 countries, 3 currencies, 4 languages, all promotion types, edge cases. Any divergence blocks ramp; no exceptions.\n\n**Shadow Mode Duration**: Run shadow traffic against live pricing requests for minimum four weeks, comparing every computed price with monolith. Measure divergence continuously. Divergence > 0.001% blocks ramp.\n\n**Gradual Cutover by Country**: Cut over per-country rather than all-at-once. Start with lowest-revenue country, validate four weeks per country, then ramp to others. Per-country flags allow independent rollback.\n\n**Rollback Path**: Keep monolith's pricing evaluator available and warm as rollback target for at least one full peak (January or July) after cutover. Maintain ability to flip back to monolith pricing via feature flag without data restore.\n\n**Four-Stage Playbook**: Stages A–D applied to pricing tables. Stage A (shadow) 4+ weeks. Stage B (read cutover) 2 weeks per country. Stage C (write cutover) per country. Stage D (cleanup) after one full peak.\n\n**Deferred Refactoring in Writing**: Publish decision that pricing rule decomposition, DSL, and optimization are explicitly deferred to follow-up program after this migration stabilizes. Include this in all project communications and retrospectives.", "dependencies": ["S5", "S6", "S7"]}, {"step_id": "S14", "title": "Extract Payment: PCI-Strict Regime and Provider-by-Provider Cutover", "description": "Extract payment processing with stricter regime than any other service. Mistakes are irreversible and regulatory. Extracted before checkout orchestration because checkout cannot be decomposed without payment boundary.\n\n**Payment Service**: Own integration with three payment providers (tokenization, authorization, capture, refund, provider webhooks). Design API: AuthorizePayment(idempotencyKey, amount, currency, cardToken, customerId) → {authorizationId, status}; CapturePayment(authorizationId); RefundPayment(captureId); HandleWebhook(webhookPayload).\n\n**PCI Scope Reduction**: No raw card data at rest in service. Card data flows directly from client to provider (tokenization); only tokens stored in Payment service. Credentials in secrets management (Vault). No card data in logs or distributed traces.\n\n**Idempotent Operations**: Explicit idempotency-key handling. Every payment request is idempotent; retries at peak are normal and must not double-charge. Implement via idempotency-key deduplication store (Redis with TTL).\n\n**Provider-by-Provider Cutover**: Cut over one provider at a time (start with lowest-volume provider). Stage A (shadow) 2 weeks per provider. Stage B (read cutover, not applicable). Stage C (write cutover) for each provider, maintain fallback to monolith for other providers. Test each provider's decline, timeout, 3-D Secure, and chargeback scenarios explicitly.\n\n**Golden Master Scenarios**: Golden master covers all three providers, all decline reasons, timeouts, partial authorizations, refund scenarios, chargebacks. Shadow traffic compares full payment outcomes (authId, status, amount, timestamp) before any live provider cutover.\n\n**Fraud Detection and 3-D Secure**: These paths are usually least-tested and most visible when broken. Test explicitly; goldne master includes fraud-decline and 3-D Secure flows. Verify fraud rules and thresholds carry over unchanged.\n\n**Fallback Orchestration**: Monolith retains ability to handle payment directly (as fallback) until second peak after Payment service cutover. Checkout can gracefully degrade to old payment path via feature flag if new service fails.\n\n**Four-Stage Playbook**: Stages A–D per provider. Stage C (write) is highest-risk; ensure golden master passes 100% and shadow mode shows zero divergence before each provider cutover. Gate and soak strictly: four weeks minimum before any freeze.\n\n**Soak and Timing**: Land in open window (Feb–May or Aug–Nov). Complete all three providers' Stage C cutover by month 9 to allow checkout orchestration time to soak before freeze.", "dependencies": ["S5", "S6", "S7"]}, {"step_id": "S15", "title": "Extract Orders: Event-Sourced Record of Truth", "description": "Extract order management as authoritative record of order lifecycle. Extracted after Inventory, Pricing, and Payment exist and are stable, because Orders depends on all three.\n\n**Orders Service**: Own order tables and order state machine. Implement explicit state transitions: Pending → Confirmed → Preparing → Shipped → Delivered, with validation blocking invalid transitions. Design API: CreateOrder(cartId, customerId, paymentAuthorizationId), GetOrder(orderId), CancelOrder(orderId), UpdateOrderStatus.\n\n**Event Sourcing**: Record all order state changes as immutable events. Build order state from event log on demand. Audit trail satisfies regulators and fulfillment teams; state can be rebuilt after incidents. Include: OrderCreated, PaymentAuthorized, InventoryReserved, OrderConfirmed, OrderPreparing, OrderShipped, OrderDelivered, OrderCancelled.\n\n**Event Consumption**: Consume events from Payment service (PaymentAuthorized, PaymentFailed), Inventory service (StockReserved, ReservationCancelled), and Returns service (ReturnInitiated, RefundIssued) rather than polling or joining.\n\n**Four-Stage Playbook**: Stages A–D. Stage A (shadow) for 1 week. Stage B (read cutover) for 2 weeks, with gradual flag ramp. Five teams that query orders start reading from Orders service via API. Stage C (write cutover): new orders written to Orders service; monolith order tables become reverse-CDC read-only replicas. Stage D after one peak.\n\n**Reconciliation: Monetary and Row-Count**: Reconcile order counts and monetary totals hourly against monolith throughout transition. Currency totals must match exactly (cent-by-cent); row count discrepancies are immediate rollback. Implement automated reconciliation query; owner assigned; threshold zero.\n\n**Concurrent Order Transitions**: Load-test concurrent order state transitions at 480k/day peak. Order state machine becomes serialization point for distributed system; ensure no race conditions, no duplicate orders, no lost transactions.\n\n**Soak Before Checkout**: Complete Orders cutover (Stages A–C) by month 9. Soak minimum four weeks before freeze. Gate to proceeding to Checkout (Step 16) is four-week soak with zero monetary reconciliation mismatches and zero order duplicates.", "dependencies": ["S9", "S13", "S14"]}, {"step_id": "S16", "title": "Extract Checkout: Distributed Saga Orchestration (Highest Risk)", "description": "Highest-risk extraction, deliberately placed last among transactional work and only after components it orchestrates are individually proven at scale. This step composes independent services into coherent checkout flow.\n\n**Checkout Orchestrator Service**: Build service that coordinates checkout: cart validation, price computation, inventory reservation, payment authorization, order creation. Design as explicit saga with named steps and compensating actions.\n\n**Saga Orchestration**: Implement synchronous saga (single coordinator) or asynchronous (choreography via events), chosen based on latency testing (target checkout p99 < 5 seconds at peak). Synchronous preferred for checkout because customer waits; failure is visible. Steps:\n1. Validate cart via Cart service\n2. Compute price via Pricing service (cached if < 1 second old)\n3. Reserve inventory via Inventory service\n4. Authorize payment via Payment service\n5. Create order via Orders service\n\n**Compensating Transactions**: For every step, define compensation:\n- Step 3 fails: Release inventory reservation\n- Step 4 fails: Release inventory reservation, void authorization (if possible)\n- Step 5 fails: Release reservation, void authorization, return payment to customer\n- Step 2 recomputes and differs: Increase price, reject order; or decrease price, accept at old price (business rules decision, document explicitly)\n\n**Idempotency End-to-End**: Checkout request includes idempotency key (unique per browser session + timestamp). Service deduplicates on this key. Retried checkout cannot double-charge or double-reserve; returns previous result.\n\n**Timeout Handling**: Inventory reservation expires in 15 minutes (configurable). Payment authorization valid for 7 days (provider-specific). Order creation never times out; if hanging, manually investigate. Saga must fail safe to retryable state, never to half-committed order.\n\n**Shadow Traffic Before Live**: Mirror live checkout traffic (100% of checkout requests during business hours) to new orchestration for minimum 2 weeks before any live cutover. Compare full outcomes: order ID, order total, inventory reservations, payment authorization IDs, error messages. Divergence > 0.001% blocks live cutover.\n\n**Live Ramp During Open Window**: Ramp live traffic only during open delivery window (Feb–May or Aug–Nov). Gate and soak strictly: minimum four weeks before freeze. Keep monolith checkout path fully functional and warm (receiving live traffic via feature flag) as rollback target until Checkout service has survived one full peak.\n\n**Peak-Readiness Gate Mandatory**: Hold six-week peak-readiness gate (Step 19) before proceeding to back-office migration (Step 18). Failed gate stops this work immediately and defers to next window.", "dependencies": ["S12", "S13", "S14", "S15"]}, {"step_id": "S17", "title": "Migrate Back-Office, Storefront, and Mobile Clients to Service APIs", "description": "Moves 300 back-office staff and client applications off monolith database direct access. Until this step, monolith database remains live dependency even where logic moved.\n\n**Back-Office Screen Refactoring**: Migrate screens table by table. Replace direct SQL with service API calls through gateway. Start with orders (call Orders service), then customers (call Customer service), then inventory (call Inventory service). Build aggregation endpoints: /orders/{id}/full-details calls Orders + Payments + Inventory + Returns services, caches 30 seconds, returns unified response.\n\n**Aggregation Endpoints and Caching**: Services are now call-chain away, not co-located. Back-office latency would suffer without caching. Implement short-lived cache (TTL 30 seconds) for frequently accessed data (customer profiles, recent orders). Graceful degradation: if one service slow, show cached data and alert staff.\n\n**Storefront and Mobile App**: Both hit same endpoints (via gateway). Update storefront (server-rendered) to call service APIs while keeping old path functional behind feature flag; rendering regression becomes flag flip, not rollback. Mobile app points at gateway for migrated endpoints; keep old endpoints alive for un-updated app versions (users do not upgrade on schedule). Implement API versioning: v1 (legacy monolith), v2 (service APIs); clients request version in Accept header.\n\n**API Versioning and Deprecation Windows**: Publish versioning rules: breaking changes trigger major version bump (v2 → v3). Old version supported for minimum 90 days after major release. Client teams must upgrade within window; do not force upgrade. Document deprecation timeline in API spec.\n\n**Load Test Back-Office Concurrency**: Test 300 concurrent staff on top of peak storefront (480k orders/day). New services now carry both loads; autoscaling and database connection pools must handle burst. Simulate realistic staff queries: order searches, customer history, bulk refunds.\n\n**Distributed Tracing for Debugging**: Every back-office request traced across services. Staff can view trace in UI; operations team can see which service was slow. Trace includes: request start, service calls, database queries, cache hits/misses.\n\n**Monitoring and Runbooks**: Create runbooks for common issues: slow customer search (check Customer service load), payment lookup fails (check Payment service), order create fails (check Orders service latency). Link from dashboard to runbook.\n\n**Gate to Monolith Decommissioning**: Back-office must be fully migrated (no direct SQL reads to monolith) before monolith core decommissioning (Step 18). This step completes organizational cutover.", "dependencies": ["S16"]}, {"step_id": "S18", "title": "Chaos Engineering, Resilience Testing, and Pre-Peak Validation", "description": "Validates new distributed architecture survives failure scenarios and peak load without cascading collapse. This step is as much about proving state is coherent as about finding failure modes.\n\n**Chaos Game Days**: Scheduled monthly (or before each peak). Kill each service in turn (Search, Inventory, Orders, Payments, etc.); confirm storefront degrades gracefully (e.g., 'Search temporarily unavailable, catalog browsing still available') rather than failing completely. Kill database replicas; verify service continues with read-only or cached data. Kill message broker; verify no events lost and no reordering. Record each game day; publish findings and mitigation actions.\n\n**Peak-Readiness Gate (Before Each Peak)**: Run six weeks before January and July peaks (mid-November, mid-May):\n- **12x Load Test**: Generate realistic 480k orders/day traffic against production-shaped data (8 countries, 3 currencies, 4 languages, realistic product hierarchy). Measure checkout p99 < 5 seconds, search p95 < 1 second, payment < 2 seconds.\n- **Capacity Headroom**: Confirm all services autoscale to handle 12x baseline. Database connection pools have headroom. Message broker partitions are sufficient. Cache hit rates do not collapse under load.\n- **Rollback Rehearsal**: Execute full rollback of most recent service extraction in load-test environment. Measure rollback time; must be < 30 minutes including data reconciliation.\n- **Error Budget Review**: Confirm SLO error budgets not burned significantly. If burned, identify culprit and mitigate before peak.\n- **Evidence Publication**: Publish load-test results, capacity headroom metrics, rollback time, and SLO status. Gate is pass/fail; failed gate defers peak exposure and triggers root-cause work.\n\n**Full System Load Test**: All services under load simultaneously. Measure inter-service latencies, database load, message broker throughput. Identify bottlenecks: pricing calculations, search queries, payment provider round-trip time, inventory reservations under concurrent access. Tune:\n- Database query indexes\n- Connection pool sizes\n- Caching strategies\n- Message broker partitions\n- Service autoscaling thresholds\n\n**Failure Mode Analysis**: Identify top 10 single-point-of-failure risks:\n1. Payment provider outage → graceful degradation (pre-authorize smaller amounts?)\n2. Inventory service down → checkout blocked; mitigation: cache inventory in checkout orchestrator\n3. Pricing service down → checkout blocked; mitigation: cache last-known prices\n4. Orders service down → checkout blocked; mitigation: queue orders in Kafka, replay when service recovers\n5. Database down → all services blocked; mitigation: read-only replicas for queries\n6. Message broker down → no events published; mitigation: outbox patterns ensure no event loss\n7. API gateway down → all traffic blocked; mitigation: active-active gateway setup (two regions or multiple providers)\n8. Warehouse sync delayed → inventory stale; mitigation: alert threshold, manual intervention process\n9. Customer service down → login blocked; mitigation: cache tokens, allow anonymous checkout\n10. Search service down → browsing blocked; mitigation: fallback to category list without search\n\nFor each failure, document mitigation (architectural change or operational procedure), test in chaos game day, and update runbooks.\n\n**Synthetic Transaction Monitoring**: Implement real-world checkout, return, and search transactions executing every five minutes. Alert on failure before customers notice. Include multi-country, multi-currency variations.\n\n**Performance Baseline Documentation**: Document baseline latencies (checkout, search, payment) at baseline load (40k orders/day). Load test must show no regression at peak; improvements accepted. Document these baselines in runbooks for operations team reference.", "dependencies": ["S17"]}, {"step_id": "S19", "title": "Monolith Decommissioning and Steady-State Operations", "description": "Safely retire monolith code once all services stable and production-proven. This step is final validation that new architecture is coherent; incomplete decommissioning signals hidden coupling.\n\n**Module-by-Module Cleanup**: Delete extracted service code from monolith only after that service has survived one full peak (January or July, whichever comes first) or four clean weeks post-cutover, whichever is longer. Before deletion:\n- Audit dead code: which stored procedures, views, tables, methods are no longer called\n- Verify service API is the only interface for data owned by extracted module\n- Confirm no service calls back into monolith code\n- Delete extracted logic and dependencies\n\n**Database Decommissioning**: Dropped tables are archived (not deleted) for 90 days (regulatory retention and emergency queries). After 90 days, drop and archive to long-term storage. Monolith database shrinks as modules extracted. When monolith becomes shell (mostly unused), decide: keep as fallback or shut down entirely.\n\n**Cross-Module Stored Procedures**: All stored procedures touching multiple modules' tables must be eliminated before monolith shutdown. If any remain, move logic into services or refactor. Document any that cannot be moved; escalate as risk.\n\n**Backup and Recovery Procedures**: Shift from single monolith snapshot to per-service snapshots. Each service team owns backup/recovery for their database. Document recovery procedures: which services recover in which order, which can tolerate data loss vs. which require point-in-time recovery. Test recovery monthly.\n\n**Architectural Decision Records**: Publish final ADRs documenting:\n- Why services were split at these boundaries\n- What problems each split solved\n- What trade-offs were made\n- What cross-service communication patterns emerged\n- What monitoring and alerting proved most useful\n\n**Operational Runbooks**: Finalize runbooks for each team:\n- Incident response: common failure modes, resolution steps, escalation paths\n- Deployment procedures: how to deploy service, rollback procedure, expected latency\n- On-call procedures: alert thresholds, page-worthy events, war room communication\n- Database procedures: backup, restore, schema migrations, connection pool tuning\n\n**Service Ownership Model**: Confirm each of five teams owns one or more services end-to-end:\n- Codebase and CI/CD pipeline\n- Database schema and migrations\n- On-call rotation and SLOs\n- Production incidents\n- Capacity planning and scaling\n\nNo shared ownership; clear escalation paths between teams.\n\n**Team Ramp-Down of Migration Work**: Migration enablement squad (formed in Step 1) transitions into steady-state platform team. Reduce migration velocity; redirect capacity to feature work on services.\n\n**Exit Criteria and Project Close**: \n- All rungs 1–6 of scope ladder complete (or deliberately stopped at rung boundary)\n- Both peak seasons (January and July) survived without migration-caused incidents\n- All services deployed independently by month 12\n- Monolith reduced to < 5% of original codebase or decommissioned entirely\n- All architectural decisions documented and team alignment confirmed\n\n**Celebrate and Document Lessons**: Publish retrospective capturing:\n- What went well: which techniques proved most valuable (golden master? chaos testing? soak periods?)\n- What was hard: which services took longer, which risks materialized\n- What would change next time\n- Which rungs of scope ladder were reached and why work stopped where it did\n\n**Deferred Work**: Explicitly list architectural or optimization work deferred to follow-up programs (e.g., Pricing DSL refactoring, read-write split at database level, multi-region deployment).", "dependencies": ["S18"]}, {"step_id": "S20", "title": "Peak Season Validation and Post-Peak Stabilization", "description": "Proves new architecture survives peak and validates migration is truly complete. January and July peaks are the final test; this step verifies readiness and documents learnings.\n\n**Pre-Peak Confirmation**: One week before peak start (Dec 25 for January peak, June 25 for July peak), confirm:\n- All peak-readiness gate checks passed\n- All services healthy and responding normally\n- Database connection pools at capacity\n- Cache hit rates normal\n- Message broker lag within SLOs\n- On-call rotations staffed\n- War room communication channels open\n\n**Peak Monitoring**: During peak (480k orders/day sustained for 2–3 weeks), maintain heightened monitoring:\n- Every service dashboard visible in central war room\n- Latency p99, p95, p50 trending in real time\n- Error rate per service alarmed\n- Database query performance monitored\n- Message broker lag tracked\n- Payment success rate watched (fraud filters, authorizations)\n- Inventory reservation accuracy validated hourly\n\n**Incident Response**: Any incident < 5 min MTTR automatically escalates to war room. Team lead validates:\n- Root cause (service slow? database? payment provider?)\n- Impact (customer-visible? checkout blocked? data corruption?)\n- Mitigation (rollback flag? scale service? throttle traffic?)\n- Recovery (how long to resolve?)\n\n**Post-Peak Retrospectives**: Within one week of peak completion, each service team retrospectives on:\n- Peak traffic patterns observed vs. load-test simulations\n- Any incidents: root cause, time-to-detect, time-to-recover\n- Performance variations: which services scaled, which became bottlenecks\n- Data accuracy: any reconciliation mismatches discovered during peak\n- Lessons for next peak\n\n**Capacity Planning**: After peak, analyze:\n- Database query times at peak: any unexpected slowdowns?\n- Service autoscaling: did services scale early enough? were there cascading failures?\n- Cache effectiveness: hit rates at peak vs. baseline\n- Message broker: any message loss or reordering?\n- Payment provider latency: did provider response times increase during peak?\n\n**Final Validation**: Confirm scope ladder rung achieved:\n- Rung 6 complete: back-office migrated, monolith core reduced, checkout orchestration stable\n- Teams deployed independently during peak (or blocked from deploying due to freeze, which is correct)\n- Zero unplanned downtime caused by migration\n- All rollback procedures worked in chaos testing; never needed in production\n\n**Program Closure**: Publish final evidence:\n- Peak season metrics (order volume, success rate, latency, errors)\n- Service-by-service stability (uptime, incidents, MTTR)\n- Scope ladder rung reached\n- Explicit deferred work list\n- Team feedback and lessons learned\n\n**Next Program Planning**: If rung 7+ desired (e.g., Pricing rules DSL refactoring, multi-region deployment), plan as separate 6-month program. Document in writing; do not creep scope into current program.", "dependencies": ["S18", "S19"]}], "estimated_complexity": "high", "success_metrics": "\n- **Zero unplanned downtime**: 100% availability throughout 12-month migration (excluding planned 30-min blue-green deployments); no production incidents attributable to migration architecture\n- **Peak seasons protected**: January and July peaks (480k orders/day) sustain zero degradation caused by migration; checkout p99 ≤ 5 seconds, payment authorization ≤ 2 seconds, error rate ≤ 0.5%, no queue backlog > 5 minutes\n- **Independent deployability**: All eight services independently deployable by month 12; each team releases on own cadence (weekly or faster) with zero cross-team deployment coordination; 100% of service releases verified rollback-capable in < 30 minutes\n- **Rollback-proven**: Every production increment has rehearsed, documented, tested rollback path (expand/contract migrations, feature flags, reverse CDC); monthly chaos game days validate rollback procedures; zero increments reach production without passing rollback gate\n- **Data consistency**: Hourly reconciliation shows < 0.001% row-count and checksum discrepancy between service databases and monolith (pre-decommissioning); zero business-invariant violations (no duplicate orders, no lost payments, no inventory oversells)\n- **Pricing correctness**: 100% agreement between new Pricing service and golden-master corpus across 1M+ historical requests covering all 8 countries, 3 currencies, 4 languages, all promotion types; zero pricing errors post-cutover\n- **Search freshness**: Product availability reflects in search within < 60 seconds of inventory change (vs. nightly rebuild); search latency p95 unchanged or improved at peak load\n- **Warehouse sync improvement**: Inventory synchronization lag reduced from 15 minutes to < 2 minutes end-to-end; 100% of daily warehouse updates processed; no missed sync cycles during migration\n- **Payment processing**: Zero regressions with all three payment providers; fraud detection active and effective; PCI-DSS compliance maintained; idempotency prevents duplicate charges; payment success rate ≥ 99.5% at peak\n- **Back-office operations unaffected**: All 300 staff seamlessly using service APIs; service aggregation endpoints maintain p95 latency ≤ 500 ms; bulk operations (refunds, order status updates) complete within SLA\n- **Test coverage for services**: All newly written service code reaches 80%+ line coverage; golden master validates 100% of public API contracts before production traffic; contract tests (Pact) prevent breaking changes between services\n- **Peak-readiness gate passed**: Six weeks before each peak (mid-November, mid-May), gate published showing 12x load test results, capacity headroom, rollback rehearsal duration, and SLO status; failed gate defers work; evidence published publicly\n- **Team independence by month 12**: Five teams deployed independently; each owns service codebase, pipeline, database schema, on-call rotation, SLOs; no cross-team pull requests blocking releases; internal developer platform (golden-path templates, self-service deployments) adopted by all teams\n- **Scope ladder completed**: Rungs 1–6 reached by month 12 (or deliberately stopped at rung boundary with documented justification); all services proven at peak; monolith reduced to < 5% or decommissioned\n- **Calendar adherence**: No major extractions or refactors during freeze windows (Dec 1–Jan 15, June 1–July 15); all production increments land in open windows with minimum 4-week soak before freeze; timeline published and adhered to\n- **Event-driven architecture validated**: Kafka message broker handles 480k+ messages/day at peak; no message loss, no ordering violations; outbox pattern ensures every domain event persists atomically\n- **Fallback capacity maintained**: Monolith rollback path kept warm and functional (receiving live traffic or ready-to-receive via feature flag) until each service survives one full peak; no service extracted without proven rollback capability\n"}It refined its strong foundation by explicitly deferring the checkout saga orchestration until after the first peak. It also clarified the mobile app versioning and authentication strategies to prevent customer disruption.
- Deferred the distributed checkout saga to a post-peak decision, keeping the transaction in the monolith during peaks.
- Added explicit abort criteria and a migration enablement squad to manage shared risks.
- Clarified that pricing dependencies are inverted via event-fed read models rather than synchronous fan-out.
- Deferring the checkout saga means the monolith remains a critical bottleneck for the core transaction throughout the year.
- The 18-step plan is dense and requires high discipline to execute without burning out the enablement squad.
- Proposal 1 : The explicit 6-week peak-season freeze framework with rehearsed rollback.
- Proposal 3 : Per-country ramps for the pricing cutover.
- Proposal 3 : Implementing the checkout saga within the 12-month migration window.
+ Calendar-first charter, scope ladder and peak-readiness protocol+ Keep the checkout transaction in the monolith for the first peak, and decide on the saga afterwards+ Decommission the extracted modules, validate the second peak, write the exit reportProgram setup, peak-aware calendar, rollback charter and scope ladderCompose Checkout from independent services using a sagaDecommission the monolith core and harden for the second peak
The plan produced
1. Calendar-first charter, scope ladder and peak-readiness protocol new
The binding constraint in this objective is the commercial calendar, not the technology, so the calendar is decided before anything else. Everything later obeys it.
- Declare the hard freezes against the real sales calendar, in the shape 1 December – 15 January and 1 June – 15 July. Inside a freeze only rollback-enabling and hardening changes ship.
- Reserve four 'risky cut' slots per year, roughly March–April and September–October. February, May, August and November are soak and hardening months and carry no new cutover.
- Forbid any cutover step from starting within six weeks of a freeze. Every cutover must end in a freeze-ready state: both paths live, flags reversible, reconciliation green.
- Publish the scope ladder. Rungs 1–8 are the core objective; rungs 9+ are optional. Slippage stops at a rung boundary in a coherent, peak-safe state, never mid-increment.
- Write the rollback charter: expand/contract schema change, feature-flag kill switch and a game-day rehearsal recorded before go-live.
- Write the abort criteria: the conditions under which the program stops, and who signs off.
- Create a migration enablement squad of six engineers on rotation from the five teams. It owns the platform, the shared cuts and the risky shared data work.
- Budget 40–50% of the five teams' capacity for migration and staff the ladder to that budget rather than filling the year.
2. Executable architecture map, table ownership and boundary enforcement (after 1)
Five teams committing to one repository will silently re-couple anything that is separated and not policed, so enforcement is part of the map, not a later step.
- Run distributed tracing on the monolith for four weeks before drawing any boundary. Real call paths beat static imports for finding true coupling.
- Build a table-to-module and query-to-module map by parsing every SQL statement, ORM mapping and stored procedure, cross-checked against the database's own query logs.
- Assign each of the 350 tables to exactly one owning module. Tables nobody can own are declared contested and scheduled into S7.
- Score each candidate service on coupling, transactional risk, change frequency and peak-path criticality. This ranking drives the extraction order, not intuition.
- Add ArchUnit rules that fail the build on new cross-module Java dependencies, and a SQL linter that fails on cross-module joins and writes. Existing violations are frozen into a baseline file that may only shrink.
- Publish the target service list, the owning team per service and the reasoning as ADRs.
- Re-rank the scope ladder at the month-six review using what the map actually showed.
3. Delivery platform: per-module pipelines, gateway, feature flags, environments (after 1, 2)
No module is extracted until its team can deploy, flag and route on its own.
- Kubernetes namespaces, quotas and autoscaling policies sized for 12x peaks.
- API gateway in front of the monolith from day one as the strangler entry point. Storefront, mobile and back-office traffic all flow through it even while it routes everything to the monolith.
- One CI/CD pipeline and one environment per module. The monolith keeps its pipeline for hotfixes until S5 replaces it.
- A feature-flag service, with every new call path flag-guarded. Flags are the primary rollback instrument for the whole program.
- Golden-path templates for a new service: build, pipeline, observability, health checks, flag integration, database migration tool.
- Two permanent environments: a production-shaped soak environment and a load-test environment able to generate 12x traffic.
- Secrets management and per-environment configuration so behaviour changes never require a monolith redeploy.
4. Observability, business SLOs and the automated rollback controller (after 3)
A canary is only trustworthy if it is judged automatically, so the rollback promise is built once here and reused by every later step.
- Centralised logging, metrics and distributed tracing, with trace correlation across gateway, monolith and every service.
- Instrument the monolith's blind spots: query latency by module, connection-pool saturation, Lucene rebuild duration, warehouse file-exchange lag.
- Define SLOs on business outcomes: checkout success rate, order confirmation p99, search latency, payment authorisation rate, price computation latency, warehouse sync freshness.
- Attach an error budget to each SLO. When a service burns budget, its rollout stops and its flags revert automatically. No negotiation during a peak.
- Build the rollback controller: on error-rate or latency divergence during a canary, the gateway shifts traffic back and disables flags without human action.
- Per-service dashboards a tired engineer can read at 03:00, plus one program dashboard showing progress against the scope ladder.
5. Split the deployment unit and retire the 30-minute maintenance window (after 2, 3)
This is the cheapest large win in the program and it delivers the headline objective — independent deployability — before any process separation, by splitting the build and the release train while the code still runs together.
- Split the single artefact into one build per owning module with a shared parent.
- Allow modules to be released as separate artefacts on the existing runtime first. Independent deployability is a build and release property long before it is a topology property.
- Retire the two-week coordinated release train. Each team gets its own pipeline, cadence and on-call rota, with the gateway and schema compatibility as the contract between teams.
- Adopt expand/contract database migrations so schema and code changes no longer have to ship together.
- Replace the maintenance window with blue-green deployment on two identical stacks, traffic switched at the gateway and rollback performed by switching back.
- Publish the measurement: deployment lead time, deployment frequency per team, and the share of releases that needed no coordination with another team.
6. Seam-level verification: golden master, contracts, shadow diffing and reconciliation (after 2, 3)
A two-million-line monolith cannot reach blanket coverage in a year. Verification is aimed exactly where the cut will be made, which is where it is affordable and where it actually pays.
- Build a characterization harness that records real production requests and responses, anonymised, as a golden master. This is the safety net for every extraction.
- Require every extracted service to pass the golden master on its public API before it takes live traffic, producing a diff report rather than a pass/fail.
- Consumer-driven contract tests between the monolith and each new service, and between services, so a breaking change breaks a build rather than production.
- Shadow traffic mirroring live requests to the new service with field-by-field comparison. The traffic ramp is gated on the divergence rate.
- Per-module data reconciliation as a first-class test: row counts, checksums and business invariants on a schedule, with an owner and an alert threshold.
- Synthetic canary transactions that run a real checkout, return and search every few minutes and alert on functional regression before customers notice.
- Track line coverage only for newly written service code, where the target is 80%. Blanket coverage of the monolith is explicitly not a goal.
7. Data platform: schema ownership, join elimination, CDC, outbox and the four-stage cutover playbook (after 2, 3, 6)
The hardest part of the program, and the part that does not depend on service extraction, so it starts in month one and runs in parallel with everything else.
- Enforce ownership inside the database: one PostgreSQL role per module, able to write only its own schema and read others only through defined views. Cross-schema writes are rejected by the database, not by convention.
- Inventory every stored procedure, attribute it to one module, and either move it into that module's code or leave it as a module-private function. After a module is extracted, no stored procedure may touch two modules' tables.
- Eliminate cross-module joins one at a time, replacing each with an API call, an event-fed read model or a duplicated read-only projection. Track the count per module and drive it to zero before that module is cut.
- Stand up change data capture with Debezium reading the PostgreSQL WAL into Kafka. This publishes monolith domain events with no application change, the lowest-risk start available.
- Add a transactional outbox for new services so their events and their state changes commit together.
- Adopt one reusable four-stage cutover playbook and apply it identically every time. Stage A: the service owns its schema logically, reads from CDC into its own store and serves shadow traffic only. Stage B: reads cut over, the monolith stays system of record. Stage C: writes cut over and the monolith's tables become read-only replicas fed by reverse CDC. Stage D: old tables and dead code are dropped only after a full peak or four clean weeks, whichever is longer.
- Make stage C genuinely reversible: because the sync direction can be flipped, rolling back a write cutover is a configuration change plus a reconciliation pass, not a data restore.
- Build the reconciliation service once, here, so every later cutover has an objective consistency check with thresholds and owners.
- Deliberately defer the 1.2 TB physical split. Services start on the existing cluster in their own schemas; physical separation is post-program work.
8. Rung 1 — Extract Catalogue and Search (after 5, 6, 7)
The first extraction: read-heavy, mostly isolated, no transactional risk. It also pays for itself, because replacing the nightly Lucene rebuild with real-time indexing is a visible business win that buys political cover for the harder cuts.
- Create a Catalog service owning product, category and media tables plus its own search index.
- Feed it from CDC so product and price changes appear in search within seconds instead of after a nightly rebuild.
- Route through the gateway behind a flag and ramp 1% → 5% → 25% → 50% → 100%, with the rollback controller able to revert to the monolith's internal Lucene path at any point.
- Run shadow traffic and compare result sets before any live traffic, then keep the old index warm for two weeks after full cutover.
- Include the mobile app in the same ramp, since it hits the same endpoints.
- Land this cut in a risky-cut slot and let it soak at least four weeks before the freeze.
9. Rung 2 — Extract Returns, the first write path (after 5, 6, 7)
Second extraction and the first that owns writes and a database. Returns is chosen because it is off the peak-critical path, has modest coupling, and exercises the full four-stage playbook at low stakes.
- Build the Returns service with its own schema, consuming order and customer events rather than joining their tables.
- Run the playbook end to end: shadow reads, read cutover, then write cutover with reverse CDC keeping the monolith's tables current.
- Prove the rollback path in a game day before write cutover, including a reconciliation pass and a re-run of the golden master.
- Keep the back-office returns screens on the monolith for now, so staff workflow is untouched by this step.
- Record every friction point and correct the playbook. The real output of this step is a proven, reusable procedure, not just one service.
10. Rung 3 — Extract Inventory and retire the 15-minute warehouse file exchange (after 5, 6, 7)
Removes one of the sharpest coupling points in the system and unblocks the checkout work. Inventory couples the monolith to an external warehouse process rather than to other modules, so it can run in parallel with the other early cuts.
- Build the Inventory service to ingest the warehouse feed directly and publish stock-level events.
- Preserve the existing file-based interface for the first weeks, running the new ingest in parallel with the legacy feed and reconciling hourly until they agree.
- Keep the monolith's inventory tables as an event-fed projection, so cart and checkout keep working unchanged during the cut.
- Design reservation semantics now — reserve, confirm, release, with expiry — even though checkout is not yet extracted. The API is needed later and is cheap to get right here.
- Load-test inventory ingest at 12x, because the warehouse feed schedule and the sales peaks do not always coincide.
- Cut over reads first, then writes, with the rollback controller able to restore the file feed as the source of truth.
11. Rung 4 — Extract Customer Accounts and Loyalty with a conservative auth strategy (after 5, 6, 7, 9)
Customer accounts and loyalty, including the authentication decision. Auth is the step that most often derails e-commerce migrations, so the auth path is deliberately moved last and guarded hardest.
- Build the Customer service owning profile, address and loyalty tables, with country-specific loyalty rules expressed as data where possible and as code where not.
- Keep authentication in the monolith for the first phase. Move token issuance only once customer data is stable, and never within four weeks of a freeze.
- Introduce distributed session handling and a token-validation API so services can verify identity without querying the monolith database.
- Cut over reads, then writes, with reverse CDC, validating against the golden master across all 8 countries and 4 languages.
- Verify the mobile app's session behaviour explicitly, since it holds long-lived sessions the storefront does not.
- Move loyalty point accrual and redemption last, because a loyalty error is a customer-visible financial error, not a technical incident.
12. Rung 5 — Extract Cart (after 8, 10, 11)
The cart is stateful and sits directly in front of checkout. It is done before pricing because the checkout path needs a stable cart boundary to call.
- Build the Cart service on Redis for session and line-item state, validating products and inventory through service calls rather than database joins.
- Make every cart operation idempotent, because a retried add or remove during a peak must not duplicate a line item.
- Keep the cart tables in the monolith as a read-only projection fed by events, for rollback and for the not-yet-migrated back-office screens.
- Ramp traffic while monitoring cart abandonment rate as the business metric, since cart latency shows up as lost revenue rather than as errors.
- Exercise anonymous and authenticated carts separately; they follow different paths and fail in different ways.
- Land this cut in a risky-cut slot with a full four-week soak before the freeze.
13. Rung 6 — Extract Pricing and Promotions as an unchanged black box (after 5, 6, 7)
Extracts the 200,000-line pricing module without rewriting it. The rules are not understood by anyone, so they are wrapped and characterized rather than reverse-engineered. Rule decomposition, documentation and a DSL are explicitly out of scope for these twelve months.
- Build a golden master corpus from at least a million real historical pricing requests and their recorded outputs, covering all 8 countries, 3 currencies, 4 languages, plus every promotion type that can be discovered.
- Invert the module's dependencies rather than its logic: pricing obtains customer, product and inventory data from event-fed read models it owns, not from synchronous fan-out to three services. A fan-out on the price path is the wrong shape at 12x peak.
- Move the pricing code into its own service unchanged, owning its tables after cutover, and expose a single decision API.
- Run it in shadow mode for at least four weeks against live traffic, comparing every computed price with the monolith. Any divergence blocks the ramp.
- Cut over behind a flag with per-country ramps, since a pricing error is a financial and legal exposure in each jurisdiction rather than a technical incident.
- Keep the in-monolith evaluator available and warm as the rollback path for at least one full peak after cutover.
- State in writing that rule decomposition is deferred to a follow-up program, so it does not creep back into this one.
14. Rung 7 — Extract Payment under a stricter regime than anything else (after 5, 6, 7)
Payment mistakes are irreversible and regulatory, so this module gets the strictest controls in the program.
- Build the Payment service owning the integration with the three providers: tokenisation, authorisation, capture, refund and provider webhooks.
- Reduce PCI scope rather than expand it. No raw card data at rest in the new service, credentials in secrets management, no card data in logs or traces.
- Make every payment operation idempotent with explicit idempotency keys, because retries at peak are normal and double charges are not recoverable.
- Cut over provider by provider rather than all three at once, starting with the lowest-volume provider.
- Run the golden master across all decline, timeout, partial-authorisation and refund scenarios, and rehearse the fallback to the monolith's direct provider integration.
- Verify fraud detection and 3-D Secure paths explicitly, since they are usually the least covered and the most visible when they break.
- Land this cut early in a risky-cut slot so it soaks well before the freeze.
15. Rung 8 — Extract Order Management with an explicit state machine (after 9, 10, 13, 14)
Order management becomes the record of truth for the order lifecycle, after the services it depends on exist and are stable.
- Build the Order service with its own database and an explicit order state machine that validates every transition.
- Introduce event sourcing for order status so the audit trail satisfies regulators and fulfilment teams, and so state can be rebuilt after an incident.
- Consume events from payment, inventory and returns rather than polling or joining.
- Cut over reads first for the five teams that query orders, then writes, keeping the monolith's order tables as a reverse-CDC projection.
- Reconcile order counts and monetary totals hourly against the monolith throughout the transition. A monetary mismatch is an immediate rollback, not a ticket.
- Load-test concurrent order state transitions at peak, since the state machine becomes the new serialisation point.
16. Keep the checkout transaction in the monolith for the first peak, and decide on the saga afterwards (after 12, 13, 14, 15) new
This is the deliberate difference from the obvious plan. Checkout is the single highest-risk cut and it sits directly on the peak-critical path. A distributed saga across pricing, inventory, payment and orders buys elegance at the cost of the two things the brief protects most: January and July sales.
- Thin the monolith's checkout into a synchronous orchestrator that calls the Pricing, Inventory, Payment and Order services through the gateway.
- Implement compensation inline in the orchestrator — a failed authorisation releases the reservation, a failed order creation voids the authorisation — without introducing a general saga framework.
- Propagate idempotency keys end to end so a retried checkout cannot double-charge or double-reserve.
- Handle the peak case explicitly: when inventory or pricing is slow, checkout must fail to a retryable state, never to a half-committed order.
- Require the peak-readiness gate before the cut that makes checkout depend on remote calls. A failed gate is a stop, not a delay; the monolith stays authoritative.
- Review after a full peak whether the orchestrator is worth extracting as a saga-based Checkout service. That decision belongs to the follow-up program, with peak data in hand.
- Document and sign off the deferral, so it is an accepted design choice rather than an unfinished step.
17. Migrate the back-office, storefront and mobile clients off the monolith database (after 16)
Until the clients move, the monolith's database stays a dependency even where the logic has already left.
- Refactor back-office screens to consume service APIs through the gateway, replacing direct SQL access table by table, starting with orders and customers.
- Add aggregation endpoints where a screen needs several services, plus a short-lived cache so 300 staff do not multiply load on the new services.
- Update the server-rendered storefront to call service APIs while keeping the existing rendering path working behind a flag, so a rendering regression is a flag flip rather than a rollback.
- Point the mobile app at the gateway for migrated endpoints and keep the old endpoints alive for un-updated app versions. No version of the app in the field may break at any point in the program.
- Publish API versioning rules and deprecation windows so teams can change their services without coordinating with client releases.
- Load-test the back-office with 300 concurrent staff on top of peak storefront traffic, since the two now share services.
18. Decommission the extracted modules, validate the second peak, write the exit report (after 17) new
Removes what is left and proves the new architecture survives a peak. This step is as much about proving the state is coherent as about deleting code.
- Delete dead code and dropped tables module by module, only after a module has run a full peak or four clean weeks, whichever is longer.
- Keep read-only access to the old database for a defined period for historical and regulatory queries, then archive and decommission it.
- Replace the monolith's remaining cross-module reads with service calls or event-fed projections. The monolith should now be a small set of modules plus the checkout orchestrator.
- Re-run the full 12x load test against the new topology across all 8 countries, 3 currencies and 4 languages, and tune autoscaling, connection pools and broker partitions from the results.
- Run chaos game days: kill each service in turn and confirm the storefront degrades gracefully rather than failing completely.
- Confirm and publish the peak-readiness gate evidence before the second peak. A failed gate defers remaining work rather than risking the peak.
- Write the exit report: final service boundaries, data ownership, runbooks, SLO history, the scope-ladder rung actually reached, and the list of work explicitly deferred to a follow-up program.
- Independent deployability: at least 4 of the 5 teams release their own artefact without coordinating with another team by month 5, and all 5 by month 9.
- The 30-minute maintenance window is retired by month 6; no release after that date requires a planned outage.
- Deployment lead time from merge to production is 30 minutes or less for a service, and each team releases at least 3 times per week by month 6.
- Zero unplanned downtime attributable to the migration across the 12 months; availability of 99.95% or better inside each peak window.
- Both January and July peaks pass with no migration-caused incident: 12x baseline load sustained, checkout p99 under 5 seconds, error rate under 0.5%, no queue backlog beyond 5 minutes.
- 100% of migration increments that reach production have a rollback demonstrated in a game day and executable in under 30 minutes.
- The rollback controller reverts a canary automatically on error-rate or latency divergence, proven in at least two live rehearsals per open window.
- Hourly reconciliation shows under 0.001% discrepancy on row counts and checksums per module; zero unexplained business-invariant violations; a monetary mismatch triggers automatic rollback.
- Cross-module joins and cross-module writes originating in application code are zero for every module at the moment it is extracted, enforced by database roles and CI rather than by review.
- Stored procedures touching more than one module's tables: zero for every extracted module.
- Pricing parity: 100% agreement with the golden master on a corpus of at least 1,000,000 historical requests across all 8 countries, 3 currencies and 4 languages, both before and after cutover.
- Search freshness improves from a nightly rebuild to under 30 seconds between a product change and its visibility in search results.
- Warehouse inventory freshness improves from 15 minutes to under 2 minutes end to end.
- Customer auth: zero forced logouts during cutover for both storefront and mobile clients, and no version of the mobile app in the field breaks at any point in the program.
- The checkout transaction remains inside the monolith through both peaks; the saga deferral is documented, accepted and signed off before month 12.
- The peak-readiness gate is passed with published evidence six weeks before both peaks, covering 100% of its defined checks.
- Scope ladder rungs 1–8 are complete within 12 months, or the program stops at a rung boundary in a documented, coherent, peak-safe state.
[SYSTEM]
You are an expert assistant in complex project planning.
Your task is to generate a detailed and structured action plan to reach the main objective in the most professional and most detailed way, no matter how much work or steps will be needed to perform.
Use your internal reasoning processes to think deeply about the problem and create the most comprehensive plan possible.
Take as much time and space as you need to think through all aspects of the problem.
After your thorough analysis, answer with the plan in the requested structure.
Every text field you write will be read by a busy person, so write for them: short sentences, one idea each, in short paragraphs. Text fields accept Markdown: separate paragraphs with a blank line, use a bullet list when you enumerate things and plain paragraphs when you explain or argue, and bold at most one key phrase per paragraph. A text of more than three sentences must be split into paragraphs; never deliver a single unbroken block of text.
[HUMAN]
Main Objective: "A mid-size European fashion retailer runs its e-commerce on a 10-year-old monolith: Java 8 / Spring, about 2 million lines, one PostgreSQL database of 1.2 TB with 350 tables and heavy use of stored procedures and cross-module joins. It serves 8 countries, 3 currencies and 4 languages, with about 40,000 orders a day and peaks of 12x during sales. The monolith contains: the storefront (server-rendered, plus a separate mobile app hitting the same endpoints), catalogue and search (a Lucene index rebuilt nightly), pricing and promotions (the most complex module, 200,000 lines, with country-specific rules nobody fully understands), cart and checkout with three payment providers, order management, inventory synchronised every 15 minutes with the warehouse system via file exchange, customer accounts and loyalty, returns, and a back-office used by 300 staff. Deployments happen every two weeks as a single artefact with a 30-minute maintenance window; test coverage is 25% and mostly unit tests. Five teams of 8 developers, each organised around a business area but all committing to the same repository.
Plan the migration to independently deployable services over 12 months with no feature freeze, no unplanned downtime and the ability to roll back every step, preserving the peak-season capacity (sales in January and July must not be put at risk)."
For your consideration and refinement, here are proposals from the previous round:
Previous Proposal 1 (ID: e20ff2ba-878c-44ab-b4e7-a66d5715df9c, Agent: claudeHaiku4.5_refine_1, LLM: anthropic/claude-haiku-4-5):
Estimated Complexity: high
Success Metrics: - Zero unplanned downtime during 12-month migration; all maintenance windows scheduled and communicated; zero production incidents caused by migration
- Peak seasons (January and July sales) proceed with zero degradation: 480k orders/day processed with p95 checkout latency < 5 seconds, payment authorization < 2 seconds, zero payment processing failures
- All eight services independently deployable: no code commits force monolith downtime; new service deployment < 5 minutes; deployment frequency increases from bi-weekly (monolith) to daily (services) where applicable
- Test coverage increased from 25% to 70%+ for all extracted services (Search, Inventory, Customer, Cart, Orders, Payments, Returns); characterization test suite for Pricing passes 100% before service extraction
- Every service deployment is rollback-able in < 30 minutes: documented procedures tested monthly; rollback automated where possible
- Data consistency validated: monthly reconciliation between service databases and monolith shows zero inconsistencies; dual-write period completes successfully (2 weeks per service)
- Order processing SLA maintained: cart → confirmation latency unchanged or improved; maintained under 5 seconds at peak load (480k orders/day)
- All five teams deploying independently by month 12: no cross-team deployment coordination required; each team owns service, deployment pipeline, on-call rotation
- Search latency improved or maintained: product availability reflected in search results within < 1 minute of inventory update (vs. previous nightly rebuild), baseline latency unchanged
- Inventory synchronization preserved: no missed 15-minute warehouse sync cycles during migration; 100% of daily inventory updates processed
- Back-office operations unaffected: 300 staff members seamlessly using new service APIs; service aggregation endpoints maintain < 500ms p95 latency
- Payment processing: zero regressions with all three payment providers; fraud detection remains active; PCI-DSS compliance maintained; idempotency prevents duplicate charges
- Event-driven architecture validated: Kafka message broker handles 480k messages/day at peak; no message loss or ordering violations
- Rollback capability proven: every step validated to be reversible; no permanent cutover without 30-day validation period and green light from peak season calendar
Steps (20):
1. Platform Foundation: Kubernetes, CI/CD, and Observability
Establish the technical foundation for independent service deployment and operation before touching the monolith architecture.
- Provision Kubernetes cluster with dev/staging/prod namespaces, or equivalent managed cloud platform (ECS/App Engine)
- Deploy centralized logging (ELK or Loki), metrics (Prometheus/Grafana), and distributed tracing (Jaeger)
- Implement CI/CD pipelines for independent service deployments (GitHub Actions/GitLab CI/ArgoCD)
- Set up secrets management (Vault) and configuration management (Consul/Spring Cloud Config)
- Create observability dashboards for: order throughput, latency percentiles (P50/P95/P99), error rates, database load
- Define SLOs and alerting: order processing latency p99 < 5 seconds, checkout success rate > 99.5%, payment auth speed < 2 seconds
2. Strangler Pattern Setup: API Gateway, Feature Flags, and Service Mesh (depends on: 1)
Deploy the infrastructure layer that enables gradual traffic migration from monolith to services without downtime.
- Deploy API gateway (Kong or AWS ALB) in front of monolith; all traffic routes through gateway
- Implement feature flag system (LaunchDarkly or Unleash) to decouple deployment from traffic routing
- Set up service mesh (Istio or Linkerd) for inter-service communication, mTLS, and circuit breakers
- Containerize monolith as-is (Docker) so it can run alongside new services
- Instrument monolith with event publishing capability: add transactional outbox table for domain events
- Create blast radius containment: rate limiting, bulkheads, and timeouts at gateway level
3. Domain Analysis and Service Boundary Definition via Event Storming (depends on: 2)
Map the monolith's business domains and dependencies to identify safe extraction sequence and service boundaries.
- Run event storming workshops with all five teams; map customer journeys (Browse → Cart → Checkout → Order → Fulfillment → Returns)
- Create dependency matrix: which tables, stored procedures, and methods are accessed by each domain
- Use code hotspot analysis (SonarQube, CodeScene) to find logical coupling and identify decoupling opportunities
- Define service extraction sequence based on coupling and business risk: prioritize read-heavy (Search), well-bounded (Inventory), and identity (Customer) over complex (Pricing, Checkout)
- Document all cross-module joins; mark which ones must be eliminated vs. which can tolerate eventual consistency
- Identify stored procedures that span multiple domains; plan refactoring or replication strategy
4. Peak Season Protection Framework and Change Freeze Calendar (depends on: 3)
Establish hard boundaries to protect January and July sales from destabilizing changes.
- Map annual peak periods: January sales (peak revenue), July sales, plus promotional events
- Define 6-week freeze windows: 4 weeks before + 2 weeks during each peak season; no major extractions or refactors during freeze
- Identify lowest-risk windows in each month for incremental changes (hotfixes, small extractions, data migrations only)
- Create rollback runbooks for every step: how to revert traffic routing, database changes, and service deployments in < 30 minutes
- Establish incident escalation and communication plan: business owners notified of any changes near peak season
- Plan load testing outside freeze windows: validate 12x capacity (480k orders/day) for each service before peak season
5. Pricing Module Characterization: Black Box Baseline and Test Suite (depends on: 3)
Thoroughly document the 200k LOC pricing engine behavior before any extraction attempt, eliminating unknown risk.
- Analyze and document all pricing rules: country-specific logic, currency handling, promotional rules, edge cases
- Create comprehensive characterization test suite: record input/output for all 8 countries × 3 currencies × major promotional scenarios
- This test suite becomes the 'golden master': any new pricing service must match 100% of outputs
- Build test data set covering: normal pricing, discounts, bulk pricing, regional pricing, multi-currency edge cases, seasonal promotions
- Document all dependencies: which customer attributes, product attributes, inventory levels, and time-based factors affect pricing
- Establish CI gate: pricing service extraction cannot proceed until characterization tests pass 100%
6. Test Coverage Improvement: Target 70% for Extract-Candidate Modules (depends on: 3)
Increase test confidence for modules scheduled for early extraction; reduce rollback risk from test blindness.
- Audit current test coverage by module; identify gaps in: Search, Catalogue, Inventory, Cart, Customer
- Implement integration tests for critical flows: order creation, payment processing, inventory updates, customer account creation
- Add contract tests (Pact) between modules to catch API breaking changes early
- Use mutation testing to verify test quality: tests must catch injected bugs
- Target 70%+ coverage for Search, Inventory, Customer, Cart, Payments modules
- Establish automated quality gates: no service extraction if module coverage < 60%; no production deployment if < 70%
- Create load test suites for peak scenarios: simulate 40k→480k order escalation for each module
7. Change Data Capture and Event-Driven Data Sync Infrastructure (depends on: 2, 5)
Build the plumbing to eliminate cross-module database joins and enable eventual consistency between services.
- Deploy CDC tool (Debezium with Kafka/Pulsar) to stream PostgreSQL WAL changes to message broker
- Refactor monolith to use transactional outbox pattern: all domain events written atomically in same transaction as business data
- Create event schema versioning: events must be backwards/forwards compatible as services evolve
- Implement dual-write mechanism: during transition, write to both monolith database and new service database
- Set up event relay: monolith publishes events (OrderPlaced, PaymentAuthorized, InventoryReserved) to Kafka
- Define eventual consistency model: which operations can tolerate delayed propagation vs. which require immediate consistency
8. Search and Catalogue Service Extraction: Read-Heavy Pilot Service (depends on: 6, 7)
Extract the first service: read-heavy, low transactional risk, validates the entire strangler fig pattern.
- Build new Catalogue and Search service: REST API for product lookup, search, and filtering
- Create new database schema (PostgreSQL): product data, categories, attributes; use Elasticsearch/OpenSearch for real-time search indexing
- Subscribe to CDC events from monolith: ProductUpdated events trigger real-time search index refresh (eliminates nightly Lucene rebuild, improves freshness to < 1 minute)
- Implement dual-read path: feature flag controls whether requests hit monolith Lucene or new Search service
- Use API gateway shadow traffic: send requests to both old and new service; compare responses; alert on differences
- Gradually shift traffic: 10% → 25% → 50% → 100% using feature flags and canary deployments
- Maintain dual-write for 2 weeks post-cutover to verify correctness; then deprecate monolith search code
9. Inventory Service Extraction: Real-Time Warehouse Synchronization (depends on: 7, 8)
Extract inventory as second service: async boundary, directly integrates with warehouse system, eliminates 15-minute sync latency.
- Build Inventory service: consumes warehouse file feed (SFTP/API) directly instead of monolith polling
- Create inventory database schema: stock levels, reservations, holds per product per location
- Publish inventory events: StockLevelChanged, ReservationCreated, ReservationReleased to Kafka
- Implement reservation system (prepare for saga pattern): inventory holds items during checkout, releases on order confirmation or timeout
- Dual-write monolith inventory data during transition: maintain consistency between old and new
- Test warehouse sync at peak load: ensure 15-minute sync windows do not slip under 480k daily orders
- Validate that all cart and checkout code calls inventory service via API (or consumes events) rather than direct SQL join
- Gradual traffic shift: test with non-critical inventory queries first, then critical paths
10. Customer and Loyalty Service Extraction: Identity Decoupling (depends on: 9)
Extract customer accounts and loyalty programs: enables independent auth scaling and multi-tenant loyalty rules.
- Build Customer service: JWT token generation, profile management, address management, identity verification
- Create customer database schema (separate from monolith): User, Address, Profile; replicate to read-only cache where needed
- Implement loyalty points service: handles country-specific loyalty rules (8 countries, different point accrual rates)
- Sync customer data via events: monolith publishes CustomerCreated, CustomerUpdated, CustomerDeleted to Kafka
- API gateway routes: /api/login, /api/profile, /api/loyalty to new Customer service; monolith drops these endpoints
- Ensure backwards compatibility: versioned API responses so old mobile app clients still work
- Test at peak concurrency: concurrent logins, loyalty point updates under 480k orders/day load
- Implement session management: distributed sessions (Redis-backed) so users stay logged in during monolith↔service transitions
11. Saga Pattern Framework and Distributed Transaction Orchestration (depends on: 7)
Implement the orchestration layer required for multi-service transactions before extracting payment and order services.
- Build saga pattern library: support both choreography (event-driven) and orchestration (centralized coordinator) patterns
- Implement compensating transactions: if payment fails during checkout, inventory reservation and pricing calc must roll back
- Add idempotency framework: all services accept idempotency-key headers; prevent duplicate charges, double-deductions
- Handle timeouts and retries: exponential backoff, circuit breakers, manual intervention for stuck sagas
- Create saga log: record saga execution with state transitions for auditing, debugging, and replay
- Test saga execution under peak load and network failures: simulate payment provider latency, inventory service timeouts
- Document saga flows: checkout saga (price → reserve inventory → authorize payment → create order), return saga, refund saga
- Implement distributed tracing: each saga step is traced end-to-end for observability
12. Payment Service Extraction: PCI-Scoped and Secure (depends on: 11)
Extract payment processing with extreme security rigor: handles card data, three payment providers, regulatory compliance.
- Build Payment service: integration with all three payment providers (tokenization, authorization, capture, refund)
- Implement PCI-DSS compliance: no raw card data in logs, encrypted transport, minimal data exposure in monolith
- Handle payment declines and fraud: integrate fraud detection, implement retry logic for transient failures
- Create idempotent payment requests: prevent double-charging if client retries or network fails mid-request
- Implement webhook handling: payment providers notify service of async events (captures, chargebacks, refunds)
- Design rollback procedure: if new service fails catastrophically, fall back to direct monolith payment handling (via feature flag)
- Load test: 500+ payments/sec at peak (baseline 40k orders/day → 480k orders/day = ~550 payments/sec)
- Test all three provider scenarios: happy path, declines, timeouts, chargebacks
13. Orders Service Extraction: Orchestrator for Checkout and Fulfillment (depends on: 12)
Extract order management: central service coordinating checkout saga and order lifecycle across all services.
- Build Order service: order creation, status tracking, order querying API for all business users (inventory, fulfillment, customer service teams)
- Implement checkout orchestrator: accepts cart (items, customer, delivery address) → triggers saga → creates order record on success
- Integrate with Payment service (authorize payment), Inventory service (reserve stock), Pricing service (calculate total), Customer service (loyalty points)
- Implement order state machine: validate state transitions (Pending → Confirmed → Shipped → Delivered), prevent invalid transitions
- Create order event stream: OrderCreated, PaymentAuthorized, InventoryReserved, OrderConfirmed, OrderShipped for other services to consume
- Use event sourcing: maintain immutable log of all order state changes for audit trail and replay capability
- Test concurrent order processing at peak load: 40k→480k orders/day; ensure no race conditions, duplicate orders, or lost transactions
- API design: query orders by customer ID, order ID, SKU, date range; sorting and filtering for back-office use
14. Cart Service Extraction: Stateful Session Management (depends on: 10)
Extract shopping cart as stateful service: decouples browsing/cart operations from order processing, independent scaling.
- Build Cart service: add/remove items, update quantities, persist session state, apply coupons/discounts
- Implement cart storage: Redis for session-backed stateless carts, or PostgreSQL with session affinity for persistent carts
- Integration with services: calls Catalogue service (product availability), Inventory service (stock check), Pricing service (cart totals)
- API design: cart operations (add/remove/view), subtotals with pricing breakdowns, coupon application
- Implement session stickiness: API gateway routes same user to same Cart service instance (or share Redis state)
- Test at peak concurrency: concurrent cart updates from same user (one browser tab → mobile app → browser again)
- Ensure idempotency: adding same item twice returns same cart state, no duplicates
- Gradual traffic shift: test with non-critical users first, then ramp up
15. Pricing Service Extraction: Black Box Wrapping and Golden Master Validation (depends on: 5, 13)
Extract pricing logic as black box service using characterization tests to ensure 100% correctness preservation.
- Move 200k LOC pricing logic into dedicated Pricing service with own codebase
- Service exposes API: accepts product IDs, customer attributes, location, time, inventory levels → returns price, applicable promotions, currency
- Use dedicated read-replica database with pricing tables only (no cross-joins to other domains)
- Run shadow mode traffic: send live pricing requests to both old monolith and new service; compare outputs; alert on any divergence
- Validation gate: pricing service must match characterization test suite 100% for all 8 countries, 3 currencies, all tested scenarios
- Feature flag control: gradually shift production traffic once shadow mode validates correctness
- Document decision: this service remains a black box (we don't refactor internal logic); future teams can safely extend without fear
- Plan Phase 2 refactoring separately: after service is stable in production, optionally decompose into rules engine (Drools) in future quarter
16. Returns Service Extraction and Order Lifecycle Completion (depends on: 13, 15)
Extract returns handling: completes order lifecycle, depends on Orders and Pricing services being stable.
- Build Returns service: process return requests, validate return eligibility, calculate refunds (using Pricing service), manage return shipping
- Integrate with Orders service: fetch order data, verify items purchased
- Integrate with Inventory service: return items to stock after confirmation
- Integrate with Payment service: process refunds back to original payment method
- API design: create return request, track return status, generate return shipping labels
- Implement return state machine: Requested → Approved → Shipped → Received → Refunded
- Consumer integration: back-office staff (or customer self-service) calls Returns service APIs instead of monolith
- Test return flows at peak load: validate no inventory/refund race conditions
17. Back-Office Service Aggregation and Staff User Experience (depends on: 13, 16)
Update back-office (300 staff) to consume new service APIs; eliminate monolith direct database access.
- Create service aggregation endpoints: orders endpoint calls Order + Payment + Inventory + Shipping services; returns endpoint calls Returns service
- Implement API gateway service discovery: back-office transparently calls services even if they move/scale
- Add caching layer: frequently accessed data (customer profiles, order lists) cached with TTL to reduce service latency
- Implement timeouts and graceful degradation: if one service is slow, show cached data or partial results
- Refactor back-office UI: replace monolith SQL queries with REST API calls
- Test with 300 concurrent staff users: search across orders/customers, filtering by date/status, bulk actions
- Implement distributed tracing: back-office requests are traced across all services for debugging
- Add retry logic: transient failures (network blips) automatically retry; permanent failures show user-friendly errors
18. Load Testing and Peak Capacity Validation Across Full System (depends on: 17)
Validate new distributed architecture handles peak load (480k orders/day) without degradation; stress test before peak seasons.
- Simulate realistic peak load: 480k orders/day (12x baseline), 8 countries, 3 currencies, 4 languages simultaneously
- Test sequence: base load → ramp to 480k → sustain for 30 minutes → spike to 1.5x peak → graceful degradation
- Measure latencies: checkout flow (cart → confirmation) p95 < 5 seconds, payment authorization < 2 seconds, search < 1 second
- Monitor service-level metrics: requests/sec, error rates, database query times, message broker throughput, cache hit rates
- Identify and optimize bottlenecks: pricing calculations, search queries, payment provider round-trip time, inventory reservations
- Test database connection pools: ensure no exhaustion or deadlocks under peak load
- Validate message broker (Kafka): 480k messages/day throughput, latency, durability
- Create realistic user behavior: product browsing → search → add to cart → checkout flows, not just load
- Fail-over testing: kill one service (e.g., Search); verify system degrades gracefully, no cascading failures
- Load test outside freeze windows; complete before January/July peak seasons
19. Team Reorganization and Independent Deployment Readiness (depends on: 18)
Reorganize teams around services to enable independent deployments and long-term operational autonomy.
- Reorganize five teams: from business-function-based (Pricing team, Fulfillment team) to stream-aligned (Search Service team, Orders Service team)
- Assign service ownership: each team owns their service's codebase, CI/CD pipeline, database schema, on-call rotation, SLOs
- Implement internal developer platform (IDP): golden path templates, self-service deployments, secrets rotation, observability dashboards
- Establish SLOs per service: error budget, latency targets, availability targets
- Create cross-team API contracts: service teams sign off on API changes; breaking changes trigger communication plan
- Set up inter-service communication: API versioning, deprecation periods, backward compatibility requirements
- Plan on-call: each team on-call for their service; pager rotation, incident response training
- Document service dependencies: which services call which; upstream/downstream impact analysis
20. Monolith Decommissioning and Legacy Code Cleanup (depends on: 19)
Safely retire monolith code once all services are stable and production-proven.
- Audit monolith codebase: identify dead code (Search, Catalogue, Inventory, Customer, Orders, Payments, Cart, Returns logic)
- Delete extracted service code from monolith; remove dual-write logic once service has proven stable (30+ days in production)
- Gradually reduce monolith database: archive or migrate old tables, remove cross-module stored procedures
- Plan monolith decommissioning: if monolith becomes shell (mostly unused), decide: keep as fallback or shut down completely
- Maintain 90-day read-only archive of monolith database for emergency historical queries and regulatory retention
- Update backup/recovery procedures: shift from single monolith snapshot to per-service snapshots
- Document architectural decisions: why services were split this way, what problems were solved, what trade-offs were made
- Create incident playbooks: common failure modes, resolution steps, escalation paths
- Close out migration project: update runbooks, retire temporary monitoring, establish steady-state operational procedures
- Celebrate: migration complete, new architecture proven at peak load, five teams deploying independently
Previous Proposal 2 (ID: 7581d19b-0670-4204-bf95-b6568fbf7cd4, Agent: deepseek-flash_refine_2 - YOUR OWN previous proposal, LLM: deepseek/deepseek-flash):
Estimated Complexity: high
Success Metrics: - Independent deployability: 100% of releases to extracted services require no coordination with another team and no monolith release, demonstrated for at least 6 services by month 9.
- Independent deployability precedes extraction: at least 4 of the 5 teams release their own artefacts without being separate services by month 5.
- The 30-minute maintenance window is retired by month 6; no release after that date requires a planned outage.
- Deployment lead time from merge to production for a single service is 30 minutes or less, and each team releases at least 3 times per week by month 6.
- Zero unplanned downtime attributable to the migration across the 12 months; platform availability of 99.95% or better inside each peak window.
- Both January and July peaks pass with no migration-caused incident: 12x baseline load sustained, checkout p99 under 5 seconds, error rate under 0.5%, no queue backlog beyond 5 minutes.
- 100% of migration increments that reach production have a rollback demonstrated in a game day and executable in under 30 minutes.
- Hourly data reconciliation shows under 0.001% discrepancy on row counts and checksums per module, with zero unexplained business-invariant violations.
- Cross-module database joins and cross-module writes originating in application code are zero for every module at the moment it is extracted, enforced by database roles and CI checks rather than by review.
- Pricing parity: 100% agreement with the golden master on a corpus of at least 1,000,000 historical requests across all 8 countries, 3 currencies and 4 languages, both before and after cutover.
- Stored procedures touching more than one module's tables: zero for every extracted module.
- Search freshness improves from a nightly rebuild to under 30 seconds between a product change and its visibility in search results.
- Warehouse inventory freshness improves from 15 minutes to under 2 minutes end to end.
- 100% of public APIs of extracted services have golden-master or consumer-driven contract coverage; line coverage is tracked only for newly written service code, where it reaches 80%.
- The peak-readiness gate is passed with published evidence six weeks before both peaks, covering 100% of its defined checks.
- Scope ladder rungs 1–6 are complete within 12 months, or the program stops at a rung boundary in a documented, coherent, peak-safe state.
Steps (18):
1. Program setup, peak-aware calendar, rollback charter and scope ladder
Turns the brief's constraints into an operating rhythm that everything later obeys. The binding constraint in this objective is the calendar, not the technology, so the calendar is decided first.
- Run a two-week inception to baseline the current state: build time, deployment lead time, change failure rate, MTTR, MTTR, per-module change frequency, database load profile. Progress must be measurable, not asserted.
- Declare hard freezes from 1 December to 15 January and 1 June to 15 July. During a freeze only rollback-enabling and hardening changes are allowed.
- Confirm the two open delivery windows of the year (roughly February–May and August–November) and accept in writing that only these windows carry migration increments.
- Set the soak rule: no change on the checkout path lands within four weeks of a freeze; anything that would violate it is deferred to the next window.
- Define the peak-readiness gate that runs six weeks before each peak: 12x load test, capacity headroom check, rollback rehearsal, error-budget review. The gate is pass/fail and its evidence is published.
- Write the rollback charter: every increment ships an expand/contract database change, a feature-flag kill switch, and a rehearsal recorded in a game day. No go-live without a rehearsed rollback.
- Publish the scope ladder: a ranked list where rungs 1–6 deliver the core objective and rungs 7+ are optional. Slippage means stopping at a rung boundary, never mid-increment.
- Set the capacity budget at 40–50% of the five teams' capacity for migration alongside normal feature work, and staff the ladder to fit that budget rather than to fill the year.
- Create a migration enablement squad of six engineers drawn on rotation from the five teams. It owns the platform, the shared cuts and the risky shared data work.
2. Executable architecture map, table ownership and boundary enforcement (depends on: 1)
Produces an architecture map that the build itself enforces. Five teams committing to one repository will silently re-couple anything that is separated and not policed, so enforcement is part of the map, not a later step.
- Instrument the monolith with distributed tracing and let it run four weeks. Real call paths beat static imports for finding true coupling.
- Build a table-to-module and query-to-module map by parsing every SQL statement, ORM mapping and stored procedure in the codebase, cross-checked against the database's own query logs.
- Score each candidate service on four axes: coupling, transactional risk, change frequency and peak-path criticality. This ranking, not intuition, drives the extraction order.
- Assign every one of the 350 tables to exactly one owning module. Tables nobody can own are declared contested and scheduled into the data work of S7.
- Add ArchUnit rules to CI that fail the build on any new cross-module Java dependency, with existing violations frozen into a baseline file that may only shrink.
- Add a SQL linter to CI that fails on cross-module joins and cross-module writes, with the same shrinking baseline.
- Publish the target service list, the owning team per service, and the reasoning as architecture decision records.
- Hold a mid-program review at month six to re-rank the scope ladder using what the map actually showed. This is the one planned re-planning point of the program.
3. Delivery platform: per-module pipelines, gateway, feature flags, environments (depends on: 1, 2)
Builds the delivery and traffic machinery that makes every later step reversible. No module is extracted until its team can deploy, flag and route on its own.
- Extend the platform foundation on Kubernetes (or the existing container platform if one exists) with one namespace per service, quotas and autoscaling policies sized for a 12x peak.
- Put an API gateway in front of the monolith as the strangler entry point. Storefront, mobile and back-office traffic all flow through it from day one, even while it routes everything to the monolith.
- Give every module its own CI/CD pipeline and its own environment. The monolith keeps its current pipeline for hotfixes until S5 replaces it.
- Deploy a feature-flag service and require every new call path to be flag-guarded. Flags are the primary rollback instrument for the whole program.
- Introduce secrets management and per-environment configuration so changing behaviour never requires a monolith redeploy.
- Define golden-path templates for a new service: build, pipeline, observability, health checks, flag integration, database migration tool. Extraction must not start from a blank page.
- Reserve two permanent environments: a full-size production-like soak environment and a load-test environment capable of generating 12x traffic against production-shaped data.
4. Observability, business SLOs, error budgets and the automated rollback controller (depends on: 3)
Makes the system observable enough that a canary is judged automatically and reverted without a human guessing. This is the prerequisite for the rollback promise made in every later step.
- Deploy centralized logging, metrics and distributed tracing, with trace correlation working across the gateway, the monolith and every new service from the start.
- Instrument the monolith's blind spots: query latency by module, connection-pool saturation, Lucene rebuild duration, warehouse file-exchange lag.
- Define SLOs on business outcomes, not infrastructure: checkout success rate, order confirmation p99, search latency, payment authorisation rate, price computation latency, warehouse sync freshness.
- Attach an error budget to each SLO and write the policy: when a service burns budget, its rollout stops automatically and its flags revert. No negotiation during a peak.
- Build the rollback controller: on error-rate or latency divergence beyond threshold during a canary, the gateway shifts traffic back and flags are disabled without human action.
- Create per-service dashboards a tired engineer can read at 03:00, plus one program dashboard showing progress against the scope ladder.
5. Split the deployment unit and retire the 30-minute maintenance window (depends on: 2, 3)
Delivers the objective's headline — independently deployable units — before any process separation, by splitting the build and the release train while the code still runs together. This is the cheapest large win available and it removes the maintenance window.
- Split the single artefact into one build per owning module with a shared parent, so a module can be built, tested and released on its own.
- Allow modules to be released as separate artefacts on the existing runtime first. Independent deployability is a build and release property long before it is a topology property.
- Retire the two-week coordinated release train. Each team gets its own pipeline, cadence and on-call rota, with the gateway and schema compatibility as the contract between teams.
- Adopt expand/contract database migrations so schema and code changes no longer have to ship together.
- Replace the maintenance window with blue-green deployment on two identical stacks, traffic switched at the gateway and rollback performed by switching back.
- Measure and publish the result: deployment lead time, deployment frequency per team, and the share of releases that needed no coordination with another team.
6. Seam-level verification: golden master, contracts, shadow diffing, reconciliation (depends on: 2, 3)
Replaces the impossible goal of blanket test coverage with verification exactly where the cut will be made. A two-million-line monolith cannot reach 70% coverage in a year; a service boundary can be verified to a very high standard in weeks.
- Build a characterization harness that records real production requests and replays them against the monolith, capturing full responses as a golden master. This is the safety net for every extraction.
- Require every extracted service to pass the golden master on its public API before it takes live traffic, producing a diff report rather than a pass/fail.
- Use consumer-driven contract tests between the monolith and each new service, and between services, so a change on one side breaks a build instead of production.
- Run shadow traffic: mirror live requests to the new service, compare responses field by field, and gate the traffic ramp on the divergence rate.
- Build per-module data reconciliation as a first-class test: row counts, checksums and business invariants compared on a schedule, with an owner and an alert threshold.
- Add synthetic canary transactions that execute a real checkout, return and search every few minutes and alert on functional regression before customers notice.
- Explicitly do not pursue blanket line coverage of the monolith. Track coverage only for newly written service code, where the target is 80%.
7. Data platform: schema ownership, join elimination, CDC, outbox, four-stage cutover playbook (depends on: 2, 3, 6)
The hardest part of the program and the part most plans under-specify. It does not depend on service extraction, so it starts in month one and runs in parallel with everything else.
- Enforce ownership inside the database itself: one PostgreSQL role per module, able to write only its own schema and to read others only through defined views. Cross-schema writes are rejected by the database, not by convention.
- Inventory every stored procedure, attribute it to one module, and either move it into that module's code or leave it as a module-private function. After a module is extracted, no stored procedure may touch two modules' tables.
- Eliminate cross-module joins one at a time, replacing each with an API call, an event-fed materialized read model or a duplicated read-only projection. Track the count per module and drive it to zero before that module is cut.
- Stand up change data capture with Debezium reading the PostgreSQL WAL into Kafka. This publishes monolith domain events with no application change, the lowest-risk start available.
- Add a transactional outbox for new services so their events and their state changes commit together.
- Adopt one reusable four-stage cutover playbook per module and apply it identically every time. Stage A: the service owns its schema logically, reads from CDC into its own store, and serves shadow traffic only. Stage B: reads cut over, the monolith stays system of record. Stage C: writes cut over, and the monolith's tables become read-only replicas fed by reverse CDC from the service. Stage D: old tables and dead code are dropped only after a full peak or four clean weeks, whichever is longer.
- Make stage C genuinely reversible: because the sync direction can be flipped, rolling back a write cutover is a configuration change plus a reconciliation pass, not a data restore.
- Build the reconciliation service now so every later cutover has an objective consistency check with thresholds and owners.
- Schedule the 1.2 TB storage migration as background work: new services start on the existing cluster with their own schemas, and physical split happens only once a module is stable.
8. Extract Catalog and Search (depends on: 5, 6, 7)
First extraction, chosen because it is read-heavy, mostly isolated and carries no transactional risk. It also pays for itself: replacing the nightly Lucene rebuild with real-time indexing is a visible business win that buys political cover for the harder cuts.
- Create a Catalog service owning product, category and media tables plus its own search index.
- Feed it from CDC so product and price changes appear in search within seconds instead of after a nightly rebuild.
- Route through the gateway behind a flag and ramp 1% → 5% → 25% → 50% → 100%, with the rollback controller able to revert to the monolith's internal Lucene path at any point.
- Run shadow traffic and compare result sets before any live traffic, then keep the old index warm for two weeks after full cutover.
- Verify the mobile app, which hits the same endpoints, inside the same ramp; its behaviour is part of the go/no-go.
- Land this cut in an open delivery window and let it soak at least four weeks before the freeze.
9. Extract Returns as the first write-path and own-database proof (depends on: 5, 6, 7)
Second extraction and the first that owns writes and a database. Returns is chosen because it is off the peak-critical path, has modest coupling, and exercises the full four-stage playbook at low stakes.
- Build the Returns service with its own schema, consuming order and customer events rather than joining their tables.
- Run the playbook end to end: shadow reads, read cutover, then write cutover with reverse CDC keeping the monolith's tables current.
- Prove the rollback path in a game day before write cutover, including a reconciliation pass and a re-run of the golden master.
- Keep the back-office returns screens on the monolith for now, so staff workflow is untouched by this step.
- Record every friction point and correct the playbook. The real output of this step is a proven, reusable procedure, not just one service.
10. Extract Inventory and replace the 15-minute warehouse file exchange (depends on: 5, 6, 7)
Removes one of the sharpest coupling points in the system and unblocks the checkout work. Inventory is extracted in parallel with the other early cuts because it couples the monolith to an external warehouse process rather than to other modules.
- Build the Inventory service to ingest the warehouse feed directly and publish stock-level events.
- Preserve the existing file-based interface for the first weeks, running the new ingest in parallel with the legacy feed and reconciling hourly until they agree.
- Keep the monolith's inventory tables as a projection fed by events, so cart and checkout keep working unchanged during the cut.
- Design reservation semantics now — reserve, confirm, release, with expiry — even though checkout is not yet extracted. The API is needed later and is cheap to get right here.
- Load-test inventory ingest at 12x, because the warehouse feed schedule and the sales peaks do not always coincide.
- Cut over reads first, then writes, with the rollback controller able to restore the file feed as the source of truth.
11. Extract Customer Accounts and Loyalty, with a conservative auth strategy (depends on: 5, 6, 7, 9)
Extracts customer accounts and loyalty, including the authentication decision. Auth is the step that most often derails e-commerce migrations, so the auth path is deliberately moved last and guarded hardest.
- Build the Customer service owning profile, address and loyalty tables, with country-specific loyalty rules expressed as data where possible and as code where not.
- Keep authentication in the monolith for the first phase. Move token issuance only once customer data is stable, and never within four weeks of a freeze.
- Introduce distributed session handling and a token-validation API so services can verify identity without querying the monolith database.
- Cut over reads, then writes, with reverse CDC, validating against the golden master across all 8 countries and 4 languages.
- Verify the mobile app's session behaviour explicitly, since it holds long-lived sessions the storefront does not.
- Move loyalty point accrual and redemption last, because a loyalty error is a customer-visible financial error, not a technical incident.
12. Extract Cart (depends on: 8, 10, 11)
Extracts the cart, which is stateful and sits directly in front of checkout. It is done before pricing and checkout because both need a stable cart boundary to call.
- Build the Cart service on Redis for session and line-item state, validating products and inventory through service calls rather than database joins.
- Make every cart operation idempotent, because a retried add or remove during a peak must not duplicate a line item.
- Keep the cart tables in the monolith as a read-only projection fed by events, for rollback and for the not-yet-migrated back-office screens.
- Ramp traffic while monitoring cart abandonment rate as the business metric, since cart latency shows up as lost revenue rather than as errors.
- Exercise anonymous and authenticated carts separately; they follow different paths and fail in different ways.
- Land this cut in an open window with a full four-week soak before the freeze.
13. Extract Pricing and Promotions as an unchanged black box (depends on: 5, 6, 7)
Extracts the 200,000-line pricing module without rewriting it. The rules are not understood by anyone, so they are wrapped and characterized rather than reverse-engineered. Rule decomposition, documentation and a DSL are explicitly out of scope for these twelve months.
- Build a golden master corpus from at least a million real historical pricing requests and their recorded outputs, covering all 8 countries, 3 currencies and 4 languages, plus every promotion type that can be discovered.
- Refactor only the module's dependencies: pricing must obtain customer, product and inventory data through interfaces rather than direct database access, so it can be lifted out.
- Move the pricing code into its own service unchanged, owning its tables after cutover, and expose a single decision API.
- Run it in shadow mode for at least four weeks against live traffic, comparing every computed price with the monolith. Any divergence blocks the ramp.
- Cut over behind a flag with per-country ramps, since a pricing error is a financial and legal exposure rather than a technical incident.
- Keep the in-monolith evaluator available and warm as the rollback path for at least one full peak after cutover.
- State in writing that rule decomposition is deferred to a follow-up program, so it does not creep back into this one.
14. Extract Payment under a stricter regime than anything else (depends on: 5, 6, 7)
Extracts payment processing, where mistakes are irreversible and regulatory. Payment is done before checkout orchestration, because checkout cannot be decomposed without a payment boundary already in place.
- Build the Payment service owning the integration with the three providers, including tokenization, authorisation, capture, refund and provider webhooks.
- Reduce PCI scope rather than expand it: no raw card data at rest in the new service, credentials in secrets management, no card data in logs or traces.
- Make every payment operation idempotent with explicit idempotency keys, because retries at peak are normal and double charges are not recoverable.
- Cut over provider by provider rather than all three at once, starting with the lowest-volume provider.
- Run the golden master across all decline, timeout, partial-authorisation and refund scenarios, and rehearse the fallback to the monolith's direct provider integration.
- Verify fraud detection and 3-D Secure paths explicitly, since they are usually the least covered and the most visible when they break.
- Land this cut early in an open window so it soaks well before the freeze.
15. Extract Order Management with an explicit state machine (depends on: 9, 10, 13, 14)
Extracts order management as the record of truth for the order lifecycle, after the services it depends on exist and are stable.
- Build the Order service with its own database and an explicit order state machine that validates every transition.
- Introduce event sourcing for order status so the audit trail satisfies regulators and fulfilment teams, and so state can be rebuilt after an incident.
- Consume events from payment, inventory and returns rather than polling or joining.
- Cut over reads first for the five teams that query orders, then writes, keeping the monolith's order tables as a reverse-CDC projection.
- Reconcile order counts and monetary totals hourly against the monolith throughout the transition. A monetary mismatch is an immediate rollback, not a ticket.
- Load-test concurrent order state transitions at peak, since the state machine becomes the new serialisation point.
16. Compose Checkout from independent services using a saga (depends on: 12, 13, 14, 15)
The highest-risk cut in the program, deliberately placed last among the transactional work and only after the components it orchestrates are individually proven.
- Build an orchestrating Checkout service that performs: cart validation, price computation, inventory reservation, payment authorisation, order creation.
- Implement compensating actions for every step: a failed authorisation releases the inventory reservation; a failed order creation voids the authorisation.
- Require idempotency keys end to end so a retried checkout cannot double-charge or double-reserve.
- Handle timeouts explicitly, including the peak case where inventory or pricing is slow. The saga must fail safe to a retryable state, never to a half-committed order.
- Mirror live checkout traffic to the new orchestration and compare full outcomes, including order totals and reservations, before any live traffic.
- Ramp live traffic during an open window only, and keep the monolith's checkout path fully functional and warm for rollback until it has survived a peak.
- Hold the six-week peak-readiness gate before this ramp and treat a failed gate as a stop, not a delay.
17. Migrate back-office, storefront and mobile clients off the monolith database (depends on: 16)
Moves the clients and the 300 back-office users onto the service APIs. Until this happens, the monolith's database remains a dependency even where the logic has already moved.
- Refactor back-office screens to consume service APIs through the gateway, replacing direct SQL access table by table, starting with orders and customers.
- Add aggregation endpoints where a screen needs several services, plus a short-lived cache so 300 staff do not multiply load on the new services.
- Update the server-rendered storefront to call service APIs while keeping the existing rendering path working behind a flag, so a rendering regression is a flag flip rather than a rollback.
- Point the mobile app at the gateway for migrated endpoints while keeping the old endpoints alive for un-updated app versions, since users do not upgrade on your schedule.
- Publish API versioning rules and deprecation windows so teams can change their services without coordinating with client releases.
- Load-test back-office behaviour with 300 concurrent staff on top of peak storefront traffic, since the two now share services.
18. Decommission the monolith core and harden for the second peak (depends on: 17)
Removes what is left of the monolith and proves the new architecture survives a peak. This step is as much about proving the state is coherent as about deleting code.
- Delete dead code and dropped tables module by module, only after a module has run a full peak or four clean weeks, whichever is longer.
- Keep read-only access to the old database for a defined period for historical and regulatory queries, then archive and decommission it.
- Replace the monolith's remaining cross-module reads with service calls or event-fed projections. The monolith should now be a small set of modules, or nothing at all.
- Re-run the full 12x load test against the new topology across all 8 countries, 3 currencies and 4 languages, and tune autoscaling, connection pools and broker partitions from the results.
- Run chaos game days: kill each service in turn and confirm the storefront degrades gracefully rather than failing completely.
- Confirm the peak-readiness gate before the second peak and publish its evidence. A failed gate defers remaining work rather than risking the peak.
- Write the exit report: final service boundaries, data ownership, runbooks, SLO history, the scope-ladder rung actually reached, and the list of work explicitly deferred to a follow-up program.
Previous Proposal 3 (ID: 10bf57da-bf5a-4286-93d2-7a544776a748, Agent: qwen3.8-flash_refine_3, LLM: alibaba/qwen3.8-flash):
Estimated Complexity: high
Success Metrics: - **Zero Downtime**: 100% availability maintained throughout the 12-month migration, excluding planned maintenance windows.
- **Rollback Speed**: Every service deployment is reversible in < 10 minutes via automated traffic switching at the Gateway.
- **Peak Performance**: The new architecture sustains 12x baseline load (480k orders/day) with < 200ms P95 latency for Checkout.
- **Data Integrity**: Zero discrepancies between pricing calculations of the old monolith and the new Pricing Service across 1 million replayed requests.
- **Independence**: Teams successfully deploy their services on a weekly cadence without coordinating with the monolith's bi-weekly release.
Steps (12):
1. Mobilization and Strategic Freeze Planning
Establish the governance and safety constraints for the migration. This step defines the 'no-touch' windows around peak seasons (January and July) and sets up the steering committee to manage the complexity of a 2M LOC codebase.
- **Team Alignment**: Reorganize the 5 teams into 'Service-First' pods. Each pod owns a target service extraction alongside their monolith maintenance duties.
- **Risk Framework**: Define strict 'Freeze Windows' (e.g., Dec 15–Jan 15, June 15–July 15) where no architectural changes are permitted, only bug fixes.
- **Dependency Mapping**: Create a 'Coupling Heatmap' identifying the most entangled modules (likely Pricing and Checkout) to isolate them for later phases.
2. Target Architecture and Domain Boundaries (depends on: 1)
Perform rigorous Domain-Driven Design (DDD) to define service boundaries. Given the 2M LOC and 350 tables, abstracting the domain is critical to prevent 'distributed monolith' outcomes.
- **Strategic DDD**: Map current modules to bounded contexts (Catalogue, Pricing, Orders, Identity, Fulfillment).
- **Database Decomposition Design**: Define the target data model for each service. Explicitly list which of the 350 tables move to which service and which cross-module joins must be replaced by API calls or events.
- **Contract Definition**: Draft API contracts (OpenAPI/GraphQL) for the core services to ensure backward compatibility with the existing frontend.
3. Core Infrastructure and Observability Foundation (depends on: 1)
Build the 'platform' that allows services to exist independently. You cannot safely extract services without first having the tools to see, test, and deploy them individually.
- **Kubernetes Cluster**: Provision a production-grade K8s environment with strict namespace isolation.
- **API Gateway**: Deploy a robust API Gateway (e.g., Kong, AWS ALB) to sit in front of the monolith. This is the 'Traffic Switcher' for the Strangler Fig pattern.
- **Observability Stack**: Implement Distributed Tracing (Jaeger), Centralized Logging (ELK/Loki), and Metrics (Prometheus). You must be able to trace a request from the gateway through a new service and back to the monolith.
- **CI/CD Pipelines**: Create independent deployment pipelines for services, allowing 15-minute rollback capabilities distinct from the monolith's 2-week cycle.
4. Test Harness: 'Golden Master' Characterization (depends on: 3)
Since testing the new logic against the old logic is the primary validation method, create an automated regression suite that captures the 'current truth' of the legacy system.
- **Input Logging**: Configure the monolith to log all incoming requests (and their responses) to a secure data lake, anonymizing PII.
- **Replay Engine**: Build a tool that takes a captured legacy request, sends it to both the legacy monolith and the new service, and diffs the responses.
- **Coverage Baseline**: Establish a 100% test coverage requirement for the *interfaces* being extracted. If you extract 'Search', you must have a test for every possible search query variant currently supported.
5. Extraction 1: Catalogue and Read-Only Search (depends on: 4)
The 'Low Hanging Fruit'. Extract the read-only Catalogue and Search capabilities first. This builds confidence and proves the Strangler Fig pattern without touching transactional data.
- **New Service**: Build 'Catalogue Service' that reads from a replicated Postgres (via logical replication) or a dedicated search DB (Elasticsearch).
- **Traffic Shift**: Configure the API Gateway to route `/products` and `/search` requests to the new service.
- **Fallback**: If the service fails, the gateway should immediately reroute to the legacy monolith (circuit breaker).
- **Optimization**: Replace the nightly Lucene rebuild with real-time indexing to instantly reflect price/inventory changes.
6. Extraction 2: Customer Identity and Profile (depends on: 5)
Extract user data handling. This decouples the 'who' from the 'what' (purchases), allowing independent authentication scaling.
- **Account Service**: Move user tables (Login, Profile, Address) to a dedicated service.
- **Session Migration**: Implement a token-passing strategy where the legacy monolith trusts tokens generated by the new Identity Service.
- **Read-Through Cache**: The legacy monolith should stop querying the user table directly; instead, it fetches user details from the Identity Service via an internal REST call or cached event.
- **Rollback**: Keep a 'sync-back' script to ensure if users are created in the new service, the legacy DB knows about them during the transition period.
7. Database Decoupling: The 'Anti-Corruption' Layer (depends on: 3, 5)
The most dangerous step. Breaking the 1.2TB DB entanglement requires intercepting the stored procedures. We stop writing to the shared DB from new services.
- **CDC Implementation**: Deploy Debezium to capture Postgres Write-Ahead Logs (WAL) into Kafka. This allows new services to be notified when the monolith updates data.
- **Outbox Pattern**: Refactor the monolith code so that when it writes to the DB, it also writes a 'domain event' to an internal Outbox table, which Debezium then publishes.
- **Read-Only Replicas**: Force new services to read from read-only replicas of the legacy DB to prevent them from causing lock contention on the master.
8. Extraction 3: Inventory and Fulfillment Interface (depends on: 7)
Move the inventory logic out. This separates the 'Stock' truth from the 'Order' truth, preparing for the complex checkout.
- **Inventory Service**: Create a service to hold the 'Single Source of Truth' for current stock levels.
- **Legacy Integration**: The monolith's checkout flow must now ask the Inventory Service to 'Reserve Stock' before processing payment.
- **Warehouse Sync**: Move the 15-minute file exchange logic into this service, isolating the legacy code from warehouse connectivity issues.
- **Concurrency Handling**: Implement optimistic locking in this service to handle high-concurrency 'reserve' requests during sales.
9. Extraction 4: Pricing and Promotions (The 'Black Box') (depends on: 8)
Extract the 200,000 LOC pricing engine. Do not rewrite the logic yet; wrap it. This is a 'Strangler Fig' step, not a refactoring step.
- **Encapsulation**: Move the existing pricing code (and its dependencies) into a new Spring Boot project called 'Pricing Service'.
- **Dependency Injection**: Replace direct DB access within the pricing logic with interfaces that call the Catalogue and Customer services via API.
- **Performance Parity**: Ensure the latency added by moving pricing to a separate network call is negligible (<50ms). Cache aggressively at the service level.
- **Validation**: Use the Golden Master (S4) to replay all historical orders and verify the new service returns the exact same price down to the cent.
10. Extraction 5: Checkout Orchestrator (Saga Pattern) (depends on: 9)
Replace the monolithic transaction with a distributed saga. This is the final piece of the transactional flow.
- **Orchestrator**: Build a lightweight service that coordinates the 'Checkout' process.
- **Saga Logic**: When an order is placed: 1. Call Pricing Service. 2. Call Inventory Service (Reserve). 3. Call Payment Gateway (External). 4. Call Order Service (Create).
- **Compensation**: If step 4 fails, the Orchestrator triggers 'Cancel Reserve' on the Inventory Service and 'Void' on the Payment Gateway.
- **Legacy Cutoff**: The monolith's 'Checkout' screen is replaced by a frontend form that calls this Orchestrator API.
11. Final Monolith Decomposition and Clean-up (depends on: 10)
At this stage, the monolith is hollowed out, containing mostly code that is called by the new services or legacy admin functions.
- **Admin Panel**: Move back-office functionality (Order management, Refunds) into a 'Management Service' that reads from the new event streams.
- **Code Deletion**: Delete the code for the extracted domains (Pricing, Search, Cart) from the monolith repository to enforce boundaries.
- **Database Cleanup**: Drop the tables owned by new services from the legacy monolith database.
- **Performance Tuning**: Optimize the remaining monolith for the only things it does: serving legacy redirects and perhaps a few 'orphaned' modules.
12. Peak Season Stress Test and Handover (depends on: 11)
Prepare for the high-volume events in Jan/July. Validate the new architecture holds under pressure.
- **Chaos Engineering**: Randomly kill the Search or Inventory services and verify the site degrades gracefully (e.g., 'Search temporarily unavailable') without crashing the checkout.
- **Load Testing**: Simulate 12x peak traffic using tools like Gatling/JMeter against the new APIs.
- **Runbooks**: Finalize operational playbooks for every team. Who owns what? How to restart a dead service? How to fallback to the monolith if the database fails?
Please, considering the previous proposals as ideas that could be considered, focus on the main objective and generate an IMPROVED proposal or a completely DIFFERENT perspective if you deem it appropriate. Only if you consider any of them is amazing and impossible to improve, answer with the same proposal.
The plan has these parts:
- "steps": the list of steps, each with "step_id" (a short label unique within this proposal, such as S1, S2, S3), "title" (a short, descriptive title), "description" (what the step does and how, in Markdown: a short opening paragraph and then, if there are several concrete things to say, a bullet list) and "dependencies" (the step_ids of the other steps of THIS proposal that must be completed first; empty if none).
- "estimated_complexity": "low", "medium" or "high".
- "success_metrics": clear and measurable success metrics, one per line as a bullet list.
Think deeply about the problem, considering all aspects and implications. Develop a comprehensive understanding of what needs to be done to achieve the objective, then produce the plan.
Answer with a single JSON object, and nothing else, that conforms to this JSON schema:
{"description": "The structure every proposing agent must answer with.", "properties": {"steps": {"items": {"description": "One step of a proposed plan. Dependencies are step_ids of the same proposal.", "properties": {"step_id": {"title": "Step Id", "type": "string"}, "title": {"title": "Title", "type": "string"}, "description": {"title": "Description", "type": "string"}, "dependencies": {"items": {"type": "string"}, "title": "Dependencies", "type": "array"}}, "required": ["step_id", "title", "description", "dependencies"], "title": "Step", "type": "object", "additionalProperties": false}, "title": "Steps", "type": "array"}, "estimated_complexity": {"title": "Estimated Complexity", "type": "string"}, "success_metrics": {"title": "Success Metrics", "type": "string"}}, "required": ["steps", "estimated_complexity", "success_metrics"], "title": "ProposalContent", "type": "object", "additionalProperties": false}
{"steps": [{"step_id": "S1", "title": "Calendar-first charter, scope ladder and peak-readiness protocol", "description": "The binding constraint in this objective is the commercial calendar, not the technology, so the calendar is decided before anything else. Everything later obeys it.\n\n- Declare the hard freezes against the real sales calendar, in the shape 1 December – 15 January and 1 June – 15 July. Inside a freeze only rollback-enabling and hardening changes ship.\n- Reserve four 'risky cut' slots per year, roughly March–April and September–October. February, May, August and November are soak and hardening months and carry no new cutover.\n- Forbid any cutover step from starting within six weeks of a freeze. Every cutover must end in a freeze-ready state: both paths live, flags reversible, reconciliation green.\n- Publish the scope ladder. Rungs 1–8 are the core objective; rungs 9+ are optional. Slippage stops at a rung boundary in a coherent, peak-safe state, never mid-increment.\n- Write the rollback charter: expand/contract schema change, feature-flag kill switch and a game-day rehearsal recorded before go-live.\n- Write the abort criteria: the conditions under which the program stops, and who signs off.\n- Create a migration enablement squad of six engineers on rotation from the five teams. It owns the platform, the shared cuts and the risky shared data work.\n- Budget 40–50% of the five teams' capacity for migration and staff the ladder to that budget rather than filling the year.", "dependencies": []}, {"step_id": "S2", "title": "Executable architecture map, table ownership and boundary enforcement", "description": "Five teams committing to one repository will silently re-couple anything that is separated and not policed, so enforcement is part of the map, not a later step.\n\n- Run distributed tracing on the monolith for four weeks before drawing any boundary. Real call paths beat static imports for finding true coupling.\n- Build a table-to-module and query-to-module map by parsing every SQL statement, ORM mapping and stored procedure, cross-checked against the database's own query logs.\n- Assign each of the 350 tables to exactly one owning module. Tables nobody can own are declared contested and scheduled into S7.\n- Score each candidate service on coupling, transactional risk, change frequency and peak-path criticality. This ranking drives the extraction order, not intuition.\n- Add ArchUnit rules that fail the build on new cross-module Java dependencies, and a SQL linter that fails on cross-module joins and writes. Existing violations are frozen into a baseline file that may only shrink.\n- Publish the target service list, the owning team per service and the reasoning as ADRs.\n- Re-rank the scope ladder at the month-six review using what the map actually showed.", "dependencies": ["S1"]}, {"step_id": "S3", "title": "Delivery platform: per-module pipelines, gateway, feature flags, environments", "description": "No module is extracted until its team can deploy, flag and route on its own.\n\n- Kubernetes namespaces, quotas and autoscaling policies sized for 12x peaks.\n- API gateway in front of the monolith from day one as the strangler entry point. Storefront, mobile and back-office traffic all flow through it even while it routes everything to the monolith.\n- One CI/CD pipeline and one environment per module. The monolith keeps its pipeline for hotfixes until S5 replaces it.\n- A feature-flag service, with every new call path flag-guarded. Flags are the primary rollback instrument for the whole program.\n- Golden-path templates for a new service: build, pipeline, observability, health checks, flag integration, database migration tool.\n- Two permanent environments: a production-shaped soak environment and a load-test environment able to generate 12x traffic.\n- Secrets management and per-environment configuration so behaviour changes never require a monolith redeploy.", "dependencies": ["S1", "S2"]}, {"step_id": "S4", "title": "Observability, business SLOs and the automated rollback controller", "description": "A canary is only trustworthy if it is judged automatically, so the rollback promise is built once here and reused by every later step.\n\n- Centralised logging, metrics and distributed tracing, with trace correlation across gateway, monolith and every service.\n- Instrument the monolith's blind spots: query latency by module, connection-pool saturation, Lucene rebuild duration, warehouse file-exchange lag.\n- Define SLOs on business outcomes: checkout success rate, order confirmation p99, search latency, payment authorisation rate, price computation latency, warehouse sync freshness.\n- Attach an error budget to each SLO. When a service burns budget, its rollout stops and its flags revert automatically. No negotiation during a peak.\n- Build the rollback controller: on error-rate or latency divergence during a canary, the gateway shifts traffic back and disables flags without human action.\n- Per-service dashboards a tired engineer can read at 03:00, plus one program dashboard showing progress against the scope ladder.", "dependencies": ["S3"]}, {"step_id": "S5", "title": "Split the deployment unit and retire the 30-minute maintenance window", "description": "This is the cheapest large win in the program and it delivers the headline objective — independent deployability — before any process separation, by splitting the build and the release train while the code still runs together.\n\n- Split the single artefact into one build per owning module with a shared parent.\n- Allow modules to be released as separate artefacts on the existing runtime first. Independent deployability is a build and release property long before it is a topology property.\n- Retire the two-week coordinated release train. Each team gets its own pipeline, cadence and on-call rota, with the gateway and schema compatibility as the contract between teams.\n- Adopt expand/contract database migrations so schema and code changes no longer have to ship together.\n- Replace the maintenance window with blue-green deployment on two identical stacks, traffic switched at the gateway and rollback performed by switching back.\n- Publish the measurement: deployment lead time, deployment frequency per team, and the share of releases that needed no coordination with another team.", "dependencies": ["S2", "S3"]}, {"step_id": "S6", "title": "Seam-level verification: golden master, contracts, shadow diffing and reconciliation", "description": "A two-million-line monolith cannot reach blanket coverage in a year. Verification is aimed exactly where the cut will be made, which is where it is affordable and where it actually pays.\n\n- Build a characterization harness that records real production requests and responses, anonymised, as a golden master. This is the safety net for every extraction.\n- Require every extracted service to pass the golden master on its public API before it takes live traffic, producing a diff report rather than a pass/fail.\n- Consumer-driven contract tests between the monolith and each new service, and between services, so a breaking change breaks a build rather than production.\n- Shadow traffic mirroring live requests to the new service with field-by-field comparison. The traffic ramp is gated on the divergence rate.\n- Per-module data reconciliation as a first-class test: row counts, checksums and business invariants on a schedule, with an owner and an alert threshold.\n- Synthetic canary transactions that run a real checkout, return and search every few minutes and alert on functional regression before customers notice.\n- Track line coverage only for newly written service code, where the target is 80%. Blanket coverage of the monolith is explicitly not a goal.", "dependencies": ["S2", "S3"]}, {"step_id": "S7", "title": "Data platform: schema ownership, join elimination, CDC, outbox and the four-stage cutover playbook", "description": "The hardest part of the program, and the part that does not depend on service extraction, so it starts in month one and runs in parallel with everything else.\n\n- Enforce ownership inside the database: one PostgreSQL role per module, able to write only its own schema and read others only through defined views. Cross-schema writes are rejected by the database, not by convention.\n- Inventory every stored procedure, attribute it to one module, and either move it into that module's code or leave it as a module-private function. After a module is extracted, no stored procedure may touch two modules' tables.\n- Eliminate cross-module joins one at a time, replacing each with an API call, an event-fed read model or a duplicated read-only projection. Track the count per module and drive it to zero before that module is cut.\n- Stand up change data capture with Debezium reading the PostgreSQL WAL into Kafka. This publishes monolith domain events with no application change, the lowest-risk start available.\n- Add a transactional outbox for new services so their events and their state changes commit together.\n- Adopt one reusable four-stage cutover playbook and apply it identically every time. Stage A: the service owns its schema logically, reads from CDC into its own store and serves shadow traffic only. Stage B: reads cut over, the monolith stays system of record. Stage C: writes cut over and the monolith's tables become read-only replicas fed by reverse CDC. Stage D: old tables and dead code are dropped only after a full peak or four clean weeks, whichever is longer.\n- Make stage C genuinely reversible: because the sync direction can be flipped, rolling back a write cutover is a configuration change plus a reconciliation pass, not a data restore.\n- Build the reconciliation service once, here, so every later cutover has an objective consistency check with thresholds and owners.\n- Deliberately defer the 1.2 TB physical split. Services start on the existing cluster in their own schemas; physical separation is post-program work.", "dependencies": ["S2", "S3", "S6"]}, {"step_id": "S8", "title": "Rung 1 — Extract Catalogue and Search", "description": "The first extraction: read-heavy, mostly isolated, no transactional risk. It also pays for itself, because replacing the nightly Lucene rebuild with real-time indexing is a visible business win that buys political cover for the harder cuts.\n\n- Create a Catalog service owning product, category and media tables plus its own search index.\n- Feed it from CDC so product and price changes appear in search within seconds instead of after a nightly rebuild.\n- Route through the gateway behind a flag and ramp 1% → 5% → 25% → 50% → 100%, with the rollback controller able to revert to the monolith's internal Lucene path at any point.\n- Run shadow traffic and compare result sets before any live traffic, then keep the old index warm for two weeks after full cutover.\n- Include the mobile app in the same ramp, since it hits the same endpoints.\n- Land this cut in a risky-cut slot and let it soak at least four weeks before the freeze.", "dependencies": ["S5", "S6", "S7"]}, {"step_id": "S9", "title": "Rung 2 — Extract Returns, the first write path", "description": "Second extraction and the first that owns writes and a database. Returns is chosen because it is off the peak-critical path, has modest coupling, and exercises the full four-stage playbook at low stakes.\n\n- Build the Returns service with its own schema, consuming order and customer events rather than joining their tables.\n- Run the playbook end to end: shadow reads, read cutover, then write cutover with reverse CDC keeping the monolith's tables current.\n- Prove the rollback path in a game day before write cutover, including a reconciliation pass and a re-run of the golden master.\n- Keep the back-office returns screens on the monolith for now, so staff workflow is untouched by this step.\n- Record every friction point and correct the playbook. The real output of this step is a proven, reusable procedure, not just one service.", "dependencies": ["S5", "S6", "S7"]}, {"step_id": "S10", "title": "Rung 3 — Extract Inventory and retire the 15-minute warehouse file exchange", "description": "Removes one of the sharpest coupling points in the system and unblocks the checkout work. Inventory couples the monolith to an external warehouse process rather than to other modules, so it can run in parallel with the other early cuts.\n\n- Build the Inventory service to ingest the warehouse feed directly and publish stock-level events.\n- Preserve the existing file-based interface for the first weeks, running the new ingest in parallel with the legacy feed and reconciling hourly until they agree.\n- Keep the monolith's inventory tables as an event-fed projection, so cart and checkout keep working unchanged during the cut.\n- Design reservation semantics now — reserve, confirm, release, with expiry — even though checkout is not yet extracted. The API is needed later and is cheap to get right here.\n- Load-test inventory ingest at 12x, because the warehouse feed schedule and the sales peaks do not always coincide.\n- Cut over reads first, then writes, with the rollback controller able to restore the file feed as the source of truth.", "dependencies": ["S5", "S6", "S7"]}, {"step_id": "S11", "title": "Rung 4 — Extract Customer Accounts and Loyalty with a conservative auth strategy", "description": "Customer accounts and loyalty, including the authentication decision. Auth is the step that most often derails e-commerce migrations, so the auth path is deliberately moved last and guarded hardest.\n\n- Build the Customer service owning profile, address and loyalty tables, with country-specific loyalty rules expressed as data where possible and as code where not.\n- Keep authentication in the monolith for the first phase. Move token issuance only once customer data is stable, and never within four weeks of a freeze.\n- Introduce distributed session handling and a token-validation API so services can verify identity without querying the monolith database.\n- Cut over reads, then writes, with reverse CDC, validating against the golden master across all 8 countries and 4 languages.\n- Verify the mobile app's session behaviour explicitly, since it holds long-lived sessions the storefront does not.\n- Move loyalty point accrual and redemption last, because a loyalty error is a customer-visible financial error, not a technical incident.", "dependencies": ["S5", "S6", "S7", "S9"]}, {"step_id": "S12", "title": "Rung 5 — Extract Cart", "description": "The cart is stateful and sits directly in front of checkout. It is done before pricing because the checkout path needs a stable cart boundary to call.\n\n- Build the Cart service on Redis for session and line-item state, validating products and inventory through service calls rather than database joins.\n- Make every cart operation idempotent, because a retried add or remove during a peak must not duplicate a line item.\n- Keep the cart tables in the monolith as a read-only projection fed by events, for rollback and for the not-yet-migrated back-office screens.\n- Ramp traffic while monitoring cart abandonment rate as the business metric, since cart latency shows up as lost revenue rather than as errors.\n- Exercise anonymous and authenticated carts separately; they follow different paths and fail in different ways.\n- Land this cut in a risky-cut slot with a full four-week soak before the freeze.", "dependencies": ["S8", "S10", "S11"]}, {"step_id": "S13", "title": "Rung 6 — Extract Pricing and Promotions as an unchanged black box", "description": "Extracts the 200,000-line pricing module without rewriting it. The rules are not understood by anyone, so they are wrapped and characterized rather than reverse-engineered. Rule decomposition, documentation and a DSL are explicitly out of scope for these twelve months.\n\n- Build a golden master corpus from at least a million real historical pricing requests and their recorded outputs, covering all 8 countries, 3 currencies, 4 languages, plus every promotion type that can be discovered.\n- Invert the module's dependencies rather than its logic: pricing obtains customer, product and inventory data from event-fed read models it owns, not from synchronous fan-out to three services. A fan-out on the price path is the wrong shape at 12x peak.\n- Move the pricing code into its own service unchanged, owning its tables after cutover, and expose a single decision API.\n- Run it in shadow mode for at least four weeks against live traffic, comparing every computed price with the monolith. Any divergence blocks the ramp.\n- Cut over behind a flag with per-country ramps, since a pricing error is a financial and legal exposure in each jurisdiction rather than a technical incident.\n- Keep the in-monolith evaluator available and warm as the rollback path for at least one full peak after cutover.\n- State in writing that rule decomposition is deferred to a follow-up program, so it does not creep back into this one.", "dependencies": ["S5", "S6", "S7"]}, {"step_id": "S14", "title": "Rung 7 — Extract Payment under a stricter regime than anything else", "description": "Payment mistakes are irreversible and regulatory, so this module gets the strictest controls in the program.\n\n- Build the Payment service owning the integration with the three providers: tokenisation, authorisation, capture, refund and provider webhooks.\n- Reduce PCI scope rather than expand it. No raw card data at rest in the new service, credentials in secrets management, no card data in logs or traces.\n- Make every payment operation idempotent with explicit idempotency keys, because retries at peak are normal and double charges are not recoverable.\n- Cut over provider by provider rather than all three at once, starting with the lowest-volume provider.\n- Run the golden master across all decline, timeout, partial-authorisation and refund scenarios, and rehearse the fallback to the monolith's direct provider integration.\n- Verify fraud detection and 3-D Secure paths explicitly, since they are usually the least covered and the most visible when they break.\n- Land this cut early in a risky-cut slot so it soaks well before the freeze.", "dependencies": ["S5", "S6", "S7"]}, {"step_id": "S15", "title": "Rung 8 — Extract Order Management with an explicit state machine", "description": "Order management becomes the record of truth for the order lifecycle, after the services it depends on exist and are stable.\n\n- Build the Order service with its own database and an explicit order state machine that validates every transition.\n- Introduce event sourcing for order status so the audit trail satisfies regulators and fulfilment teams, and so state can be rebuilt after an incident.\n- Consume events from payment, inventory and returns rather than polling or joining.\n- Cut over reads first for the five teams that query orders, then writes, keeping the monolith's order tables as a reverse-CDC projection.\n- Reconcile order counts and monetary totals hourly against the monolith throughout the transition. A monetary mismatch is an immediate rollback, not a ticket.\n- Load-test concurrent order state transitions at peak, since the state machine becomes the new serialisation point.", "dependencies": ["S9", "S10", "S13", "S14"]}, {"step_id": "S16", "title": "Keep the checkout transaction in the monolith for the first peak, and decide on the saga afterwards", "description": "This is the deliberate difference from the obvious plan. Checkout is the single highest-risk cut and it sits directly on the peak-critical path. A distributed saga across pricing, inventory, payment and orders buys elegance at the cost of the two things the brief protects most: January and July sales.\n\n- Thin the monolith's checkout into a synchronous orchestrator that calls the Pricing, Inventory, Payment and Order services through the gateway.\n- Implement compensation inline in the orchestrator — a failed authorisation releases the reservation, a failed order creation voids the authorisation — without introducing a general saga framework.\n- Propagate idempotency keys end to end so a retried checkout cannot double-charge or double-reserve.\n- Handle the peak case explicitly: when inventory or pricing is slow, checkout must fail to a retryable state, never to a half-committed order.\n- Require the peak-readiness gate before the cut that makes checkout depend on remote calls. A failed gate is a stop, not a delay; the monolith stays authoritative.\n- Review after a full peak whether the orchestrator is worth extracting as a saga-based Checkout service. That decision belongs to the follow-up program, with peak data in hand.\n- Document and sign off the deferral, so it is an accepted design choice rather than an unfinished step.", "dependencies": ["S12", "S13", "S14", "S15"]}, {"step_id": "S17", "title": "Migrate the back-office, storefront and mobile clients off the monolith database", "description": "Until the clients move, the monolith's database stays a dependency even where the logic has already left.\n\n- Refactor back-office screens to consume service APIs through the gateway, replacing direct SQL access table by table, starting with orders and customers.\n- Add aggregation endpoints where a screen needs several services, plus a short-lived cache so 300 staff do not multiply load on the new services.\n- Update the server-rendered storefront to call service APIs while keeping the existing rendering path working behind a flag, so a rendering regression is a flag flip rather than a rollback.\n- Point the mobile app at the gateway for migrated endpoints and keep the old endpoints alive for un-updated app versions. No version of the app in the field may break at any point in the program.\n- Publish API versioning rules and deprecation windows so teams can change their services without coordinating with client releases.\n- Load-test the back-office with 300 concurrent staff on top of peak storefront traffic, since the two now share services.", "dependencies": ["S16"]}, {"step_id": "S18", "title": "Decommission the extracted modules, validate the second peak, write the exit report", "description": "Removes what is left and proves the new architecture survives a peak. This step is as much about proving the state is coherent as about deleting code.\n\n- Delete dead code and dropped tables module by module, only after a module has run a full peak or four clean weeks, whichever is longer.\n- Keep read-only access to the old database for a defined period for historical and regulatory queries, then archive and decommission it.\n- Replace the monolith's remaining cross-module reads with service calls or event-fed projections. The monolith should now be a small set of modules plus the checkout orchestrator.\n- Re-run the full 12x load test against the new topology across all 8 countries, 3 currencies and 4 languages, and tune autoscaling, connection pools and broker partitions from the results.\n- Run chaos game days: kill each service in turn and confirm the storefront degrades gracefully rather than failing completely.\n- Confirm and publish the peak-readiness gate evidence before the second peak. A failed gate defers remaining work rather than risking the peak.\n- Write the exit report: final service boundaries, data ownership, runbooks, SLO history, the scope-ladder rung actually reached, and the list of work explicitly deferred to a follow-up program.", "dependencies": ["S17"]}], "estimated_complexity": "high", "success_metrics": "- Independent deployability: at least 4 of the 5 teams release their own artefact without coordinating with another team by month 5, and all 5 by month 9.\n- The 30-minute maintenance window is retired by month 6; no release after that date requires a planned outage.\n- Deployment lead time from merge to production is 30 minutes or less for a service, and each team releases at least 3 times per week by month 6.\n- Zero unplanned downtime attributable to the migration across the 12 months; availability of 99.95% or better inside each peak window.\n- Both January and July peaks pass with no migration-caused incident: 12x baseline load sustained, checkout p99 under 5 seconds, error rate under 0.5%, no queue backlog beyond 5 minutes.\n- 100% of migration increments that reach production have a rollback demonstrated in a game day and executable in under 30 minutes.\n- The rollback controller reverts a canary automatically on error-rate or latency divergence, proven in at least two live rehearsals per open window.\n- Hourly reconciliation shows under 0.001% discrepancy on row counts and checksums per module; zero unexplained business-invariant violations; a monetary mismatch triggers automatic rollback.\n- Cross-module joins and cross-module writes originating in application code are zero for every module at the moment it is extracted, enforced by database roles and CI rather than by review.\n- Stored procedures touching more than one module's tables: zero for every extracted module.\n- Pricing parity: 100% agreement with the golden master on a corpus of at least 1,000,000 historical requests across all 8 countries, 3 currencies and 4 languages, both before and after cutover.\n- Search freshness improves from a nightly rebuild to under 30 seconds between a product change and its visibility in search results.\n- Warehouse inventory freshness improves from 15 minutes to under 2 minutes end to end.\n- Customer auth: zero forced logouts during cutover for both storefront and mobile clients, and no version of the mobile app in the field breaks at any point in the program.\n- The checkout transaction remains inside the monolith through both peaks; the saga deferral is documented, accepted and signed off before month 12.\n- The peak-readiness gate is passed with published evidence six weeks before both peaks, covering 100% of its defined checks.\n- Scope ladder rungs 1–8 are complete within 12 months, or the program stops at a rung boundary in a documented, coherent, peak-safe state."}It adopted the golden master and CDC strategies from the other proposals, improving its data and testing rigor. However, it still lacks the operational depth of the four-stage cutover playbook and explicit rollback rehearsals.
- Adopted the Golden Master replay engine for pricing and critical paths.
- Moved Inventory extraction earlier to unblock real-time stock visibility.
- Extracted a dedicated Payment service to isolate PCI scope from the Checkout orchestrator.
- The four-stage cutover playbook is glossed over, leaving data migration risks under-specified.
- Lacks explicit rollback game-day rehearsals and automated rollback controllers.
- Proposal 2 : Seam-level verification and data platform enforcement.
- Proposal 1 : Black-box extraction for the pricing module.
- Proposal 2 : Deferring the checkout saga orchestration to a post-peak decision.
+ Program Governance, Peak Calendar, and Scope Ladder+ Data Foundation: CDC, Outbox Pattern, and Transactional Events+ Architectural Decoupling: Table Ownership and Anti-Corruption Layer+ Characterization Test Harness: The Golden Master+ First Extraction Pilot: Catalogue and Search (Read-Heavy)+ Third Extraction: Customer Profile and Identity+ Core Transactional Extraction: Orders and Order Management+ Checkout Orchestration and Saga Implementation+ Payment Provider Integration Service+ Return and Refund Workflow Extraction+ Operational Handover and Autonomous Team SetupStrangler Pattern Setup: API Gateway, Feature Flags, and Service MeshDomain Analysis and Service Boundary Definition via Event StormingPeak Season Protection Framework and Change Freeze CalendarTest Coverage Improvement: Target 70% for Extract-Candidate ModulesChange Data Capture and Event-Driven Data Sync InfrastructureSearch and Catalogue Service Extraction: Read-Heavy Pilot ServiceCustomer and Loyalty Service Extraction: Identity DecouplingSaga Pattern Framework and Distributed Transaction OrchestrationPayment Service Extraction: PCI-Scoped and SecureOrders Service Extraction: Orchestrator for Checkout and FulfillmentCart Service Extraction: Stateful Session ManagementPricing Service Extraction: Black Box Wrapping and Golden Master ValidationReturns Service Extraction and Order Lifecycle CompletionLoad Testing and Peak Capacity Validation Across Full SystemTeam Reorganization and Independent Deployment Readiness
The plan produced
1. Program Governance, Peak Calendar, and Scope Ladder from P2 step 1
Establish the binding constraints of the program before any technical work begins. The calendar dictates that the January and July sales peaks are immovable objects; therefore, all migration steps must be scheduled around them.
2. Platform Foundation: Kubernetes, Gateway, and Observability (after 1) from P1 step 1
Deploy the infrastructure layer required to run services independently and observe traffic flow. This includes a Kubernetes cluster for workloads, an API Gateway as the central routing control point, and a full observability stack (Tracing, Metrics, Logs). The Gateway is the primary mechanism for rollback via traffic shifting.
3. Data Foundation: CDC, Outbox Pattern, and Transactional Events (after 1, 2) new
Implement Change Data Capture (Debezium) and a Transactional Outbox pattern in the monolith. This creates the event backbone required for eventual consistency and allows new services to subscribe to monolith changes without touching the legacy code logic. This step runs in parallel with platform setup.
4. Architectural Decoupling: Table Ownership and Anti-Corruption Layer (after 2)
Define strict ownership for the 350 tables and implement an Anti-Corruption Layer (ACL) to intercept cross-module dependencies. This involves creating separate database schemas or logical boundaries for high-coupling areas like Orders and Catalogue to prepare for physical separation.
5. Characterization Test Harness: The Golden Master (after 2, 3) new
Build a replay engine and capture a 'Golden Master' corpus of production traffic. This automated test suite records request/response pairs from the monolith, creating a baseline for validation. This is critical for the Pricing module and high-traffic endpoints where refactoring is impossible.
6. First Extraction Pilot: Catalogue and Search (Read-Heavy) (after 3, 4, 5)
Extract the Catalogue and Search services. These are low-risk (read-heavy) and validate the strangler fig pattern. Implement real-time search indexing via CDC events, replacing the nightly Lucene rebuild. Use the Golden Master to verify product data and search results match the monolith.
7. Second Extraction: Inventory Synchronization (after 3, 5) from P1 step 9
Extract Inventory management, specifically handling the integration with the external warehouse system (15-minute sync). This removes a critical dependency from the monolith and enables real-time stock visibility. The service acts as the single source of truth for stock levels.
8. Third Extraction: Customer Profile and Identity (after 3, 4)
Extract Customer Accounts and Profile management. Move authentication logic and customer data ownership to a dedicated service. Ensure the Mobile App and Storefront can authenticate against the new service while maintaining session compatibility via JWT or shared session state.
9. Pricing Module Stabilization: Black Box Extraction (after 5) from P1 step 5
Extract the 200,000 LOC Pricing and Promotions module as a 'Black Box' service. Do not refactor the logic; wrap it. Use the Golden Master to validate 100% accuracy across all 8 countries and complex promotion rules. This step is strictly scheduled outside of any peak season.
10. Core Transactional Extraction: Orders and Order Management (after 6, 7, 8, 9) new
Extract the Order Management domain, including order creation, state machines, and lifecycle tracking. This service acts as the consumer of events from Inventory, Pricing, and Customer services. It replaces the monolith's direct order processing logic.
11. Checkout Orchestration and Saga Implementation (after 7, 9, 10)
Implement the Checkout Service, acting as the orchestrator (Saga) for the payment process. It coordinates the distributed transaction across Cart, Pricing, Inventory, and Payments. It handles compensating transactions (e.g., releasing inventory on payment failure) to ensure data consistency.
12. Payment Provider Integration Service (after 10, 11) new
Extract the logic responsible for connecting to the three payment providers. This service handles authorization, capture, and refunds. By isolating this, the monolith no longer holds sensitive payment processing logic, reducing PCI scope and coupling.
13. Return and Refund Workflow Extraction (after 10, 12) new
Extract the Returns and Refunds logic. This service consumes order events to trigger return workflows, updates inventory, and requests refunds from the Payment Service. This completes the reverse logistics capability as a microservice.
14. Legacy Monolith Decommissioning: Strangler Finish (after 10, 11, 12, 13) from P1 step 20
Remove the extracted logic from the monolith. The monolith is now a legacy shell containing only the storefront rendering layer (which delegates to APIs) and potentially the Back-Office (if not yet migrated). This step involves rigorous cleanup of unused code and database tables.
15. Back-Office Migration and Staff Tooling (after 14) from P1 step 17
Migrate the Back-Office (300 staff users) to use the new service APIs. This may involve a dedicated BFF (Backend for Frontend) service that aggregates data from Orders, Customers, and Inventory for the staff UI, replacing direct database joins in the monolith.
16. Operational Handover and Autonomous Team Setup (after 15) new
Finalize team ownership. Each of the five teams is assigned to specific services (e.g., Team A owns Inventory and Search, Team B owns Orders and Checkout). Transfer on-call rotations and disaster recovery runbooks to the new services.
- Zero unplanned downtime during the 12-month migration and subsequent peaks.
- Peak season (Jan/Jul) capacity maintained at 12x baseline with no performance degradation in checkout flows.
- 100% of Pricing and Promotion transactions match the Golden Master characterization tests post-extraction.
- Five teams deploying independently at least once per week without coordination conflicts.
- All monolith-to-service data synchronization latency under 2 seconds (near real-time).
- Database size reduced by >40% through extraction and cleanup of legacy unused tables.
- Search index refresh time reduced from 24 hours (nightly) to < 1 minute (real-time).
[SYSTEM]
You are an expert assistant in complex project planning.
Your task is to generate a detailed and structured action plan to reach the main objective in the most professional and most detailed way, no matter how much work or steps will be needed to perform.
Use your internal reasoning processes to think deeply about the problem and create the most comprehensive plan possible.
Take as much time and space as you need to think through all aspects of the problem.
After your thorough analysis, answer with the plan in the requested structure.
Every text field you write will be read by a busy person, so write for them: short sentences, one idea each, in short paragraphs. Text fields accept Markdown: separate paragraphs with a blank line, use a bullet list when you enumerate things and plain paragraphs when you explain or argue, and bold at most one key phrase per paragraph. A text of more than three sentences must be split into paragraphs; never deliver a single unbroken block of text.
[HUMAN]
Main Objective: "A mid-size European fashion retailer runs its e-commerce on a 10-year-old monolith: Java 8 / Spring, about 2 million lines, one PostgreSQL database of 1.2 TB with 350 tables and heavy use of stored procedures and cross-module joins. It serves 8 countries, 3 currencies and 4 languages, with about 40,000 orders a day and peaks of 12x during sales. The monolith contains: the storefront (server-rendered, plus a separate mobile app hitting the same endpoints), catalogue and search (a Lucene index rebuilt nightly), pricing and promotions (the most complex module, 200,000 lines, with country-specific rules nobody fully understands), cart and checkout with three payment providers, order management, inventory synchronised every 15 minutes with the warehouse system via file exchange, customer accounts and loyalty, returns, and a back-office used by 300 staff. Deployments happen every two weeks as a single artefact with a 30-minute maintenance window; test coverage is 25% and mostly unit tests. Five teams of 8 developers, each organised around a business area but all committing to the same repository.
Plan the migration to independently deployable services over 12 months with no feature freeze, no unplanned downtime and the ability to roll back every step, preserving the peak-season capacity (sales in January and July must not be put at risk)."
For your consideration and refinement, here are proposals from the previous round:
Previous Proposal 1 (ID: e20ff2ba-878c-44ab-b4e7-a66d5715df9c, Agent: claudeHaiku4.5_refine_1, LLM: anthropic/claude-haiku-4-5):
Estimated Complexity: high
Success Metrics: - Zero unplanned downtime during 12-month migration; all maintenance windows scheduled and communicated; zero production incidents caused by migration
- Peak seasons (January and July sales) proceed with zero degradation: 480k orders/day processed with p95 checkout latency < 5 seconds, payment authorization < 2 seconds, zero payment processing failures
- All eight services independently deployable: no code commits force monolith downtime; new service deployment < 5 minutes; deployment frequency increases from bi-weekly (monolith) to daily (services) where applicable
- Test coverage increased from 25% to 70%+ for all extracted services (Search, Inventory, Customer, Cart, Orders, Payments, Returns); characterization test suite for Pricing passes 100% before service extraction
- Every service deployment is rollback-able in < 30 minutes: documented procedures tested monthly; rollback automated where possible
- Data consistency validated: monthly reconciliation between service databases and monolith shows zero inconsistencies; dual-write period completes successfully (2 weeks per service)
- Order processing SLA maintained: cart → confirmation latency unchanged or improved; maintained under 5 seconds at peak load (480k orders/day)
- All five teams deploying independently by month 12: no cross-team deployment coordination required; each team owns service, deployment pipeline, on-call rotation
- Search latency improved or maintained: product availability reflected in search results within < 1 minute of inventory update (vs. previous nightly rebuild), baseline latency unchanged
- Inventory synchronization preserved: no missed 15-minute warehouse sync cycles during migration; 100% of daily inventory updates processed
- Back-office operations unaffected: 300 staff members seamlessly using new service APIs; service aggregation endpoints maintain < 500ms p95 latency
- Payment processing: zero regressions with all three payment providers; fraud detection remains active; PCI-DSS compliance maintained; idempotency prevents duplicate charges
- Event-driven architecture validated: Kafka message broker handles 480k messages/day at peak; no message loss or ordering violations
- Rollback capability proven: every step validated to be reversible; no permanent cutover without 30-day validation period and green light from peak season calendar
Steps (20):
1. Platform Foundation: Kubernetes, CI/CD, and Observability
Establish the technical foundation for independent service deployment and operation before touching the monolith architecture.
- Provision Kubernetes cluster with dev/staging/prod namespaces, or equivalent managed cloud platform (ECS/App Engine)
- Deploy centralized logging (ELK or Loki), metrics (Prometheus/Grafana), and distributed tracing (Jaeger)
- Implement CI/CD pipelines for independent service deployments (GitHub Actions/GitLab CI/ArgoCD)
- Set up secrets management (Vault) and configuration management (Consul/Spring Cloud Config)
- Create observability dashboards for: order throughput, latency percentiles (P50/P95/P99), error rates, database load
- Define SLOs and alerting: order processing latency p99 < 5 seconds, checkout success rate > 99.5%, payment auth speed < 2 seconds
2. Strangler Pattern Setup: API Gateway, Feature Flags, and Service Mesh (depends on: 1)
Deploy the infrastructure layer that enables gradual traffic migration from monolith to services without downtime.
- Deploy API gateway (Kong or AWS ALB) in front of monolith; all traffic routes through gateway
- Implement feature flag system (LaunchDarkly or Unleash) to decouple deployment from traffic routing
- Set up service mesh (Istio or Linkerd) for inter-service communication, mTLS, and circuit breakers
- Containerize monolith as-is (Docker) so it can run alongside new services
- Instrument monolith with event publishing capability: add transactional outbox table for domain events
- Create blast radius containment: rate limiting, bulkheads, and timeouts at gateway level
3. Domain Analysis and Service Boundary Definition via Event Storming (depends on: 2)
Map the monolith's business domains and dependencies to identify safe extraction sequence and service boundaries.
- Run event storming workshops with all five teams; map customer journeys (Browse → Cart → Checkout → Order → Fulfillment → Returns)
- Create dependency matrix: which tables, stored procedures, and methods are accessed by each domain
- Use code hotspot analysis (SonarQube, CodeScene) to find logical coupling and identify decoupling opportunities
- Define service extraction sequence based on coupling and business risk: prioritize read-heavy (Search), well-bounded (Inventory), and identity (Customer) over complex (Pricing, Checkout)
- Document all cross-module joins; mark which ones must be eliminated vs. which can tolerate eventual consistency
- Identify stored procedures that span multiple domains; plan refactoring or replication strategy
4. Peak Season Protection Framework and Change Freeze Calendar (depends on: 3)
Establish hard boundaries to protect January and July sales from destabilizing changes.
- Map annual peak periods: January sales (peak revenue), July sales, plus promotional events
- Define 6-week freeze windows: 4 weeks before + 2 weeks during each peak season; no major extractions or refactors during freeze
- Identify lowest-risk windows in each month for incremental changes (hotfixes, small extractions, data migrations only)
- Create rollback runbooks for every step: how to revert traffic routing, database changes, and service deployments in < 30 minutes
- Establish incident escalation and communication plan: business owners notified of any changes near peak season
- Plan load testing outside freeze windows: validate 12x capacity (480k orders/day) for each service before peak season
5. Pricing Module Characterization: Black Box Baseline and Test Suite (depends on: 3)
Thoroughly document the 200k LOC pricing engine behavior before any extraction attempt, eliminating unknown risk.
- Analyze and document all pricing rules: country-specific logic, currency handling, promotional rules, edge cases
- Create comprehensive characterization test suite: record input/output for all 8 countries × 3 currencies × major promotional scenarios
- This test suite becomes the 'golden master': any new pricing service must match 100% of outputs
- Build test data set covering: normal pricing, discounts, bulk pricing, regional pricing, multi-currency edge cases, seasonal promotions
- Document all dependencies: which customer attributes, product attributes, inventory levels, and time-based factors affect pricing
- Establish CI gate: pricing service extraction cannot proceed until characterization tests pass 100%
6. Test Coverage Improvement: Target 70% for Extract-Candidate Modules (depends on: 3)
Increase test confidence for modules scheduled for early extraction; reduce rollback risk from test blindness.
- Audit current test coverage by module; identify gaps in: Search, Catalogue, Inventory, Cart, Customer
- Implement integration tests for critical flows: order creation, payment processing, inventory updates, customer account creation
- Add contract tests (Pact) between modules to catch API breaking changes early
- Use mutation testing to verify test quality: tests must catch injected bugs
- Target 70%+ coverage for Search, Inventory, Customer, Cart, Payments modules
- Establish automated quality gates: no service extraction if module coverage < 60%; no production deployment if < 70%
- Create load test suites for peak scenarios: simulate 40k→480k order escalation for each module
7. Change Data Capture and Event-Driven Data Sync Infrastructure (depends on: 2, 5)
Build the plumbing to eliminate cross-module database joins and enable eventual consistency between services.
- Deploy CDC tool (Debezium with Kafka/Pulsar) to stream PostgreSQL WAL changes to message broker
- Refactor monolith to use transactional outbox pattern: all domain events written atomically in same transaction as business data
- Create event schema versioning: events must be backwards/forwards compatible as services evolve
- Implement dual-write mechanism: during transition, write to both monolith database and new service database
- Set up event relay: monolith publishes events (OrderPlaced, PaymentAuthorized, InventoryReserved) to Kafka
- Define eventual consistency model: which operations can tolerate delayed propagation vs. which require immediate consistency
8. Search and Catalogue Service Extraction: Read-Heavy Pilot Service (depends on: 6, 7)
Extract the first service: read-heavy, low transactional risk, validates the entire strangler fig pattern.
- Build new Catalogue and Search service: REST API for product lookup, search, and filtering
- Create new database schema (PostgreSQL): product data, categories, attributes; use Elasticsearch/OpenSearch for real-time search indexing
- Subscribe to CDC events from monolith: ProductUpdated events trigger real-time search index refresh (eliminates nightly Lucene rebuild, improves freshness to < 1 minute)
- Implement dual-read path: feature flag controls whether requests hit monolith Lucene or new Search service
- Use API gateway shadow traffic: send requests to both old and new service; compare responses; alert on differences
- Gradually shift traffic: 10% → 25% → 50% → 100% using feature flags and canary deployments
- Maintain dual-write for 2 weeks post-cutover to verify correctness; then deprecate monolith search code
9. Inventory Service Extraction: Real-Time Warehouse Synchronization (depends on: 7, 8)
Extract inventory as second service: async boundary, directly integrates with warehouse system, eliminates 15-minute sync latency.
- Build Inventory service: consumes warehouse file feed (SFTP/API) directly instead of monolith polling
- Create inventory database schema: stock levels, reservations, holds per product per location
- Publish inventory events: StockLevelChanged, ReservationCreated, ReservationReleased to Kafka
- Implement reservation system (prepare for saga pattern): inventory holds items during checkout, releases on order confirmation or timeout
- Dual-write monolith inventory data during transition: maintain consistency between old and new
- Test warehouse sync at peak load: ensure 15-minute sync windows do not slip under 480k daily orders
- Validate that all cart and checkout code calls inventory service via API (or consumes events) rather than direct SQL join
- Gradual traffic shift: test with non-critical inventory queries first, then critical paths
10. Customer and Loyalty Service Extraction: Identity Decoupling (depends on: 9)
Extract customer accounts and loyalty programs: enables independent auth scaling and multi-tenant loyalty rules.
- Build Customer service: JWT token generation, profile management, address management, identity verification
- Create customer database schema (separate from monolith): User, Address, Profile; replicate to read-only cache where needed
- Implement loyalty points service: handles country-specific loyalty rules (8 countries, different point accrual rates)
- Sync customer data via events: monolith publishes CustomerCreated, CustomerUpdated, CustomerDeleted to Kafka
- API gateway routes: /api/login, /api/profile, /api/loyalty to new Customer service; monolith drops these endpoints
- Ensure backwards compatibility: versioned API responses so old mobile app clients still work
- Test at peak concurrency: concurrent logins, loyalty point updates under 480k orders/day load
- Implement session management: distributed sessions (Redis-backed) so users stay logged in during monolith↔service transitions
11. Saga Pattern Framework and Distributed Transaction Orchestration (depends on: 7)
Implement the orchestration layer required for multi-service transactions before extracting payment and order services.
- Build saga pattern library: support both choreography (event-driven) and orchestration (centralized coordinator) patterns
- Implement compensating transactions: if payment fails during checkout, inventory reservation and pricing calc must roll back
- Add idempotency framework: all services accept idempotency-key headers; prevent duplicate charges, double-deductions
- Handle timeouts and retries: exponential backoff, circuit breakers, manual intervention for stuck sagas
- Create saga log: record saga execution with state transitions for auditing, debugging, and replay
- Test saga execution under peak load and network failures: simulate payment provider latency, inventory service timeouts
- Document saga flows: checkout saga (price → reserve inventory → authorize payment → create order), return saga, refund saga
- Implement distributed tracing: each saga step is traced end-to-end for observability
12. Payment Service Extraction: PCI-Scoped and Secure (depends on: 11)
Extract payment processing with extreme security rigor: handles card data, three payment providers, regulatory compliance.
- Build Payment service: integration with all three payment providers (tokenization, authorization, capture, refund)
- Implement PCI-DSS compliance: no raw card data in logs, encrypted transport, minimal data exposure in monolith
- Handle payment declines and fraud: integrate fraud detection, implement retry logic for transient failures
- Create idempotent payment requests: prevent double-charging if client retries or network fails mid-request
- Implement webhook handling: payment providers notify service of async events (captures, chargebacks, refunds)
- Design rollback procedure: if new service fails catastrophically, fall back to direct monolith payment handling (via feature flag)
- Load test: 500+ payments/sec at peak (baseline 40k orders/day → 480k orders/day = ~550 payments/sec)
- Test all three provider scenarios: happy path, declines, timeouts, chargebacks
13. Orders Service Extraction: Orchestrator for Checkout and Fulfillment (depends on: 12)
Extract order management: central service coordinating checkout saga and order lifecycle across all services.
- Build Order service: order creation, status tracking, order querying API for all business users (inventory, fulfillment, customer service teams)
- Implement checkout orchestrator: accepts cart (items, customer, delivery address) → triggers saga → creates order record on success
- Integrate with Payment service (authorize payment), Inventory service (reserve stock), Pricing service (calculate total), Customer service (loyalty points)
- Implement order state machine: validate state transitions (Pending → Confirmed → Shipped → Delivered), prevent invalid transitions
- Create order event stream: OrderCreated, PaymentAuthorized, InventoryReserved, OrderConfirmed, OrderShipped for other services to consume
- Use event sourcing: maintain immutable log of all order state changes for audit trail and replay capability
- Test concurrent order processing at peak load: 40k→480k orders/day; ensure no race conditions, duplicate orders, or lost transactions
- API design: query orders by customer ID, order ID, SKU, date range; sorting and filtering for back-office use
14. Cart Service Extraction: Stateful Session Management (depends on: 10)
Extract shopping cart as stateful service: decouples browsing/cart operations from order processing, independent scaling.
- Build Cart service: add/remove items, update quantities, persist session state, apply coupons/discounts
- Implement cart storage: Redis for session-backed stateless carts, or PostgreSQL with session affinity for persistent carts
- Integration with services: calls Catalogue service (product availability), Inventory service (stock check), Pricing service (cart totals)
- API design: cart operations (add/remove/view), subtotals with pricing breakdowns, coupon application
- Implement session stickiness: API gateway routes same user to same Cart service instance (or share Redis state)
- Test at peak concurrency: concurrent cart updates from same user (one browser tab → mobile app → browser again)
- Ensure idempotency: adding same item twice returns same cart state, no duplicates
- Gradual traffic shift: test with non-critical users first, then ramp up
15. Pricing Service Extraction: Black Box Wrapping and Golden Master Validation (depends on: 5, 13)
Extract pricing logic as black box service using characterization tests to ensure 100% correctness preservation.
- Move 200k LOC pricing logic into dedicated Pricing service with own codebase
- Service exposes API: accepts product IDs, customer attributes, location, time, inventory levels → returns price, applicable promotions, currency
- Use dedicated read-replica database with pricing tables only (no cross-joins to other domains)
- Run shadow mode traffic: send live pricing requests to both old monolith and new service; compare outputs; alert on any divergence
- Validation gate: pricing service must match characterization test suite 100% for all 8 countries, 3 currencies, all tested scenarios
- Feature flag control: gradually shift production traffic once shadow mode validates correctness
- Document decision: this service remains a black box (we don't refactor internal logic); future teams can safely extend without fear
- Plan Phase 2 refactoring separately: after service is stable in production, optionally decompose into rules engine (Drools) in future quarter
16. Returns Service Extraction and Order Lifecycle Completion (depends on: 13, 15)
Extract returns handling: completes order lifecycle, depends on Orders and Pricing services being stable.
- Build Returns service: process return requests, validate return eligibility, calculate refunds (using Pricing service), manage return shipping
- Integrate with Orders service: fetch order data, verify items purchased
- Integrate with Inventory service: return items to stock after confirmation
- Integrate with Payment service: process refunds back to original payment method
- API design: create return request, track return status, generate return shipping labels
- Implement return state machine: Requested → Approved → Shipped → Received → Refunded
- Consumer integration: back-office staff (or customer self-service) calls Returns service APIs instead of monolith
- Test return flows at peak load: validate no inventory/refund race conditions
17. Back-Office Service Aggregation and Staff User Experience (depends on: 13, 16)
Update back-office (300 staff) to consume new service APIs; eliminate monolith direct database access.
- Create service aggregation endpoints: orders endpoint calls Order + Payment + Inventory + Shipping services; returns endpoint calls Returns service
- Implement API gateway service discovery: back-office transparently calls services even if they move/scale
- Add caching layer: frequently accessed data (customer profiles, order lists) cached with TTL to reduce service latency
- Implement timeouts and graceful degradation: if one service is slow, show cached data or partial results
- Refactor back-office UI: replace monolith SQL queries with REST API calls
- Test with 300 concurrent staff users: search across orders/customers, filtering by date/status, bulk actions
- Implement distributed tracing: back-office requests are traced across all services for debugging
- Add retry logic: transient failures (network blips) automatically retry; permanent failures show user-friendly errors
18. Load Testing and Peak Capacity Validation Across Full System (depends on: 17)
Validate new distributed architecture handles peak load (480k orders/day) without degradation; stress test before peak seasons.
- Simulate realistic peak load: 480k orders/day (12x baseline), 8 countries, 3 currencies, 4 languages simultaneously
- Test sequence: base load → ramp to 480k → sustain for 30 minutes → spike to 1.5x peak → graceful degradation
- Measure latencies: checkout flow (cart → confirmation) p95 < 5 seconds, payment authorization < 2 seconds, search < 1 second
- Monitor service-level metrics: requests/sec, error rates, database query times, message broker throughput, cache hit rates
- Identify and optimize bottlenecks: pricing calculations, search queries, payment provider round-trip time, inventory reservations
- Test database connection pools: ensure no exhaustion or deadlocks under peak load
- Validate message broker (Kafka): 480k messages/day throughput, latency, durability
- Create realistic user behavior: product browsing → search → add to cart → checkout flows, not just load
- Fail-over testing: kill one service (e.g., Search); verify system degrades gracefully, no cascading failures
- Load test outside freeze windows; complete before January/July peak seasons
19. Team Reorganization and Independent Deployment Readiness (depends on: 18)
Reorganize teams around services to enable independent deployments and long-term operational autonomy.
- Reorganize five teams: from business-function-based (Pricing team, Fulfillment team) to stream-aligned (Search Service team, Orders Service team)
- Assign service ownership: each team owns their service's codebase, CI/CD pipeline, database schema, on-call rotation, SLOs
- Implement internal developer platform (IDP): golden path templates, self-service deployments, secrets rotation, observability dashboards
- Establish SLOs per service: error budget, latency targets, availability targets
- Create cross-team API contracts: service teams sign off on API changes; breaking changes trigger communication plan
- Set up inter-service communication: API versioning, deprecation periods, backward compatibility requirements
- Plan on-call: each team on-call for their service; pager rotation, incident response training
- Document service dependencies: which services call which; upstream/downstream impact analysis
20. Monolith Decommissioning and Legacy Code Cleanup (depends on: 19)
Safely retire monolith code once all services are stable and production-proven.
- Audit monolith codebase: identify dead code (Search, Catalogue, Inventory, Customer, Orders, Payments, Cart, Returns logic)
- Delete extracted service code from monolith; remove dual-write logic once service has proven stable (30+ days in production)
- Gradually reduce monolith database: archive or migrate old tables, remove cross-module stored procedures
- Plan monolith decommissioning: if monolith becomes shell (mostly unused), decide: keep as fallback or shut down completely
- Maintain 90-day read-only archive of monolith database for emergency historical queries and regulatory retention
- Update backup/recovery procedures: shift from single monolith snapshot to per-service snapshots
- Document architectural decisions: why services were split this way, what problems were solved, what trade-offs were made
- Create incident playbooks: common failure modes, resolution steps, escalation paths
- Close out migration project: update runbooks, retire temporary monitoring, establish steady-state operational procedures
- Celebrate: migration complete, new architecture proven at peak load, five teams deploying independently
Previous Proposal 2 (ID: 7581d19b-0670-4204-bf95-b6568fbf7cd4, Agent: deepseek-flash_refine_2, LLM: deepseek/deepseek-flash):
Estimated Complexity: high
Success Metrics: - Independent deployability: 100% of releases to extracted services require no coordination with another team and no monolith release, demonstrated for at least 6 services by month 9.
- Independent deployability precedes extraction: at least 4 of the 5 teams release their own artefacts without being separate services by month 5.
- The 30-minute maintenance window is retired by month 6; no release after that date requires a planned outage.
- Deployment lead time from merge to production for a single service is 30 minutes or less, and each team releases at least 3 times per week by month 6.
- Zero unplanned downtime attributable to the migration across the 12 months; platform availability of 99.95% or better inside each peak window.
- Both January and July peaks pass with no migration-caused incident: 12x baseline load sustained, checkout p99 under 5 seconds, error rate under 0.5%, no queue backlog beyond 5 minutes.
- 100% of migration increments that reach production have a rollback demonstrated in a game day and executable in under 30 minutes.
- Hourly data reconciliation shows under 0.001% discrepancy on row counts and checksums per module, with zero unexplained business-invariant violations.
- Cross-module database joins and cross-module writes originating in application code are zero for every module at the moment it is extracted, enforced by database roles and CI checks rather than by review.
- Pricing parity: 100% agreement with the golden master on a corpus of at least 1,000,000 historical requests across all 8 countries, 3 currencies and 4 languages, both before and after cutover.
- Stored procedures touching more than one module's tables: zero for every extracted module.
- Search freshness improves from a nightly rebuild to under 30 seconds between a product change and its visibility in search results.
- Warehouse inventory freshness improves from 15 minutes to under 2 minutes end to end.
- 100% of public APIs of extracted services have golden-master or consumer-driven contract coverage; line coverage is tracked only for newly written service code, where it reaches 80%.
- The peak-readiness gate is passed with published evidence six weeks before both peaks, covering 100% of its defined checks.
- Scope ladder rungs 1–6 are complete within 12 months, or the program stops at a rung boundary in a documented, coherent, peak-safe state.
Steps (18):
1. Program setup, peak-aware calendar, rollback charter and scope ladder
Turns the brief's constraints into an operating rhythm that everything later obeys. The binding constraint in this objective is the calendar, not the technology, so the calendar is decided first.
- Run a two-week inception to baseline the current state: build time, deployment lead time, change failure rate, MTTR, MTTR, per-module change frequency, database load profile. Progress must be measurable, not asserted.
- Declare hard freezes from 1 December to 15 January and 1 June to 15 July. During a freeze only rollback-enabling and hardening changes are allowed.
- Confirm the two open delivery windows of the year (roughly February–May and August–November) and accept in writing that only these windows carry migration increments.
- Set the soak rule: no change on the checkout path lands within four weeks of a freeze; anything that would violate it is deferred to the next window.
- Define the peak-readiness gate that runs six weeks before each peak: 12x load test, capacity headroom check, rollback rehearsal, error-budget review. The gate is pass/fail and its evidence is published.
- Write the rollback charter: every increment ships an expand/contract database change, a feature-flag kill switch, and a rehearsal recorded in a game day. No go-live without a rehearsed rollback.
- Publish the scope ladder: a ranked list where rungs 1–6 deliver the core objective and rungs 7+ are optional. Slippage means stopping at a rung boundary, never mid-increment.
- Set the capacity budget at 40–50% of the five teams' capacity for migration alongside normal feature work, and staff the ladder to fit that budget rather than to fill the year.
- Create a migration enablement squad of six engineers drawn on rotation from the five teams. It owns the platform, the shared cuts and the risky shared data work.
2. Executable architecture map, table ownership and boundary enforcement (depends on: 1)
Produces an architecture map that the build itself enforces. Five teams committing to one repository will silently re-couple anything that is separated and not policed, so enforcement is part of the map, not a later step.
- Instrument the monolith with distributed tracing and let it run four weeks. Real call paths beat static imports for finding true coupling.
- Build a table-to-module and query-to-module map by parsing every SQL statement, ORM mapping and stored procedure in the codebase, cross-checked against the database's own query logs.
- Score each candidate service on four axes: coupling, transactional risk, change frequency and peak-path criticality. This ranking, not intuition, drives the extraction order.
- Assign every one of the 350 tables to exactly one owning module. Tables nobody can own are declared contested and scheduled into the data work of S7.
- Add ArchUnit rules to CI that fail the build on any new cross-module Java dependency, with existing violations frozen into a baseline file that may only shrink.
- Add a SQL linter to CI that fails on cross-module joins and cross-module writes, with the same shrinking baseline.
- Publish the target service list, the owning team per service, and the reasoning as architecture decision records.
- Hold a mid-program review at month six to re-rank the scope ladder using what the map actually showed. This is the one planned re-planning point of the program.
3. Delivery platform: per-module pipelines, gateway, feature flags, environments (depends on: 1, 2)
Builds the delivery and traffic machinery that makes every later step reversible. No module is extracted until its team can deploy, flag and route on its own.
- Extend the platform foundation on Kubernetes (or the existing container platform if one exists) with one namespace per service, quotas and autoscaling policies sized for a 12x peak.
- Put an API gateway in front of the monolith as the strangler entry point. Storefront, mobile and back-office traffic all flow through it from day one, even while it routes everything to the monolith.
- Give every module its own CI/CD pipeline and its own environment. The monolith keeps its current pipeline for hotfixes until S5 replaces it.
- Deploy a feature-flag service and require every new call path to be flag-guarded. Flags are the primary rollback instrument for the whole program.
- Introduce secrets management and per-environment configuration so changing behaviour never requires a monolith redeploy.
- Define golden-path templates for a new service: build, pipeline, observability, health checks, flag integration, database migration tool. Extraction must not start from a blank page.
- Reserve two permanent environments: a full-size production-like soak environment and a load-test environment capable of generating 12x traffic against production-shaped data.
4. Observability, business SLOs, error budgets and the automated rollback controller (depends on: 3)
Makes the system observable enough that a canary is judged automatically and reverted without a human guessing. This is the prerequisite for the rollback promise made in every later step.
- Deploy centralized logging, metrics and distributed tracing, with trace correlation working across the gateway, the monolith and every new service from the start.
- Instrument the monolith's blind spots: query latency by module, connection-pool saturation, Lucene rebuild duration, warehouse file-exchange lag.
- Define SLOs on business outcomes, not infrastructure: checkout success rate, order confirmation p99, search latency, payment authorisation rate, price computation latency, warehouse sync freshness.
- Attach an error budget to each SLO and write the policy: when a service burns budget, its rollout stops automatically and its flags revert. No negotiation during a peak.
- Build the rollback controller: on error-rate or latency divergence beyond threshold during a canary, the gateway shifts traffic back and flags are disabled without human action.
- Create per-service dashboards a tired engineer can read at 03:00, plus one program dashboard showing progress against the scope ladder.
5. Split the deployment unit and retire the 30-minute maintenance window (depends on: 2, 3)
Delivers the objective's headline — independently deployable units — before any process separation, by splitting the build and the release train while the code still runs together. This is the cheapest large win available and it removes the maintenance window.
- Split the single artefact into one build per owning module with a shared parent, so a module can be built, tested and released on its own.
- Allow modules to be released as separate artefacts on the existing runtime first. Independent deployability is a build and release property long before it is a topology property.
- Retire the two-week coordinated release train. Each team gets its own pipeline, cadence and on-call rota, with the gateway and schema compatibility as the contract between teams.
- Adopt expand/contract database migrations so schema and code changes no longer have to ship together.
- Replace the maintenance window with blue-green deployment on two identical stacks, traffic switched at the gateway and rollback performed by switching back.
- Measure and publish the result: deployment lead time, deployment frequency per team, and the share of releases that needed no coordination with another team.
6. Seam-level verification: golden master, contracts, shadow diffing, reconciliation (depends on: 2, 3)
Replaces the impossible goal of blanket test coverage with verification exactly where the cut will be made. A two-million-line monolith cannot reach 70% coverage in a year; a service boundary can be verified to a very high standard in weeks.
- Build a characterization harness that records real production requests and replays them against the monolith, capturing full responses as a golden master. This is the safety net for every extraction.
- Require every extracted service to pass the golden master on its public API before it takes live traffic, producing a diff report rather than a pass/fail.
- Use consumer-driven contract tests between the monolith and each new service, and between services, so a change on one side breaks a build instead of production.
- Run shadow traffic: mirror live requests to the new service, compare responses field by field, and gate the traffic ramp on the divergence rate.
- Build per-module data reconciliation as a first-class test: row counts, checksums and business invariants compared on a schedule, with an owner and an alert threshold.
- Add synthetic canary transactions that execute a real checkout, return and search every few minutes and alert on functional regression before customers notice.
- Explicitly do not pursue blanket line coverage of the monolith. Track coverage only for newly written service code, where the target is 80%.
7. Data platform: schema ownership, join elimination, CDC, outbox, four-stage cutover playbook (depends on: 2, 3, 6)
The hardest part of the program and the part most plans under-specify. It does not depend on service extraction, so it starts in month one and runs in parallel with everything else.
- Enforce ownership inside the database itself: one PostgreSQL role per module, able to write only its own schema and to read others only through defined views. Cross-schema writes are rejected by the database, not by convention.
- Inventory every stored procedure, attribute it to one module, and either move it into that module's code or leave it as a module-private function. After a module is extracted, no stored procedure may touch two modules' tables.
- Eliminate cross-module joins one at a time, replacing each with an API call, an event-fed materialized read model or a duplicated read-only projection. Track the count per module and drive it to zero before that module is cut.
- Stand up change data capture with Debezium reading the PostgreSQL WAL into Kafka. This publishes monolith domain events with no application change, the lowest-risk start available.
- Add a transactional outbox for new services so their events and their state changes commit together.
- Adopt one reusable four-stage cutover playbook per module and apply it identically every time. Stage A: the service owns its schema logically, reads from CDC into its own store, and serves shadow traffic only. Stage B: reads cut over, the monolith stays system of record. Stage C: writes cut over, and the monolith's tables become read-only replicas fed by reverse CDC from the service. Stage D: old tables and dead code are dropped only after a full peak or four clean weeks, whichever is longer.
- Make stage C genuinely reversible: because the sync direction can be flipped, rolling back a write cutover is a configuration change plus a reconciliation pass, not a data restore.
- Build the reconciliation service now so every later cutover has an objective consistency check with thresholds and owners.
- Schedule the 1.2 TB storage migration as background work: new services start on the existing cluster with their own schemas, and physical split happens only once a module is stable.
8. Extract Catalog and Search (depends on: 5, 6, 7)
First extraction, chosen because it is read-heavy, mostly isolated and carries no transactional risk. It also pays for itself: replacing the nightly Lucene rebuild with real-time indexing is a visible business win that buys political cover for the harder cuts.
- Create a Catalog service owning product, category and media tables plus its own search index.
- Feed it from CDC so product and price changes appear in search within seconds instead of after a nightly rebuild.
- Route through the gateway behind a flag and ramp 1% → 5% → 25% → 50% → 100%, with the rollback controller able to revert to the monolith's internal Lucene path at any point.
- Run shadow traffic and compare result sets before any live traffic, then keep the old index warm for two weeks after full cutover.
- Verify the mobile app, which hits the same endpoints, inside the same ramp; its behaviour is part of the go/no-go.
- Land this cut in an open delivery window and let it soak at least four weeks before the freeze.
9. Extract Returns as the first write-path and own-database proof (depends on: 5, 6, 7)
Second extraction and the first that owns writes and a database. Returns is chosen because it is off the peak-critical path, has modest coupling, and exercises the full four-stage playbook at low stakes.
- Build the Returns service with its own schema, consuming order and customer events rather than joining their tables.
- Run the playbook end to end: shadow reads, read cutover, then write cutover with reverse CDC keeping the monolith's tables current.
- Prove the rollback path in a game day before write cutover, including a reconciliation pass and a re-run of the golden master.
- Keep the back-office returns screens on the monolith for now, so staff workflow is untouched by this step.
- Record every friction point and correct the playbook. The real output of this step is a proven, reusable procedure, not just one service.
10. Extract Inventory and replace the 15-minute warehouse file exchange (depends on: 5, 6, 7)
Removes one of the sharpest coupling points in the system and unblocks the checkout work. Inventory is extracted in parallel with the other early cuts because it couples the monolith to an external warehouse process rather than to other modules.
- Build the Inventory service to ingest the warehouse feed directly and publish stock-level events.
- Preserve the existing file-based interface for the first weeks, running the new ingest in parallel with the legacy feed and reconciling hourly until they agree.
- Keep the monolith's inventory tables as a projection fed by events, so cart and checkout keep working unchanged during the cut.
- Design reservation semantics now — reserve, confirm, release, with expiry — even though checkout is not yet extracted. The API is needed later and is cheap to get right here.
- Load-test inventory ingest at 12x, because the warehouse feed schedule and the sales peaks do not always coincide.
- Cut over reads first, then writes, with the rollback controller able to restore the file feed as the source of truth.
11. Extract Customer Accounts and Loyalty, with a conservative auth strategy (depends on: 5, 6, 7, 9)
Extracts customer accounts and loyalty, including the authentication decision. Auth is the step that most often derails e-commerce migrations, so the auth path is deliberately moved last and guarded hardest.
- Build the Customer service owning profile, address and loyalty tables, with country-specific loyalty rules expressed as data where possible and as code where not.
- Keep authentication in the monolith for the first phase. Move token issuance only once customer data is stable, and never within four weeks of a freeze.
- Introduce distributed session handling and a token-validation API so services can verify identity without querying the monolith database.
- Cut over reads, then writes, with reverse CDC, validating against the golden master across all 8 countries and 4 languages.
- Verify the mobile app's session behaviour explicitly, since it holds long-lived sessions the storefront does not.
- Move loyalty point accrual and redemption last, because a loyalty error is a customer-visible financial error, not a technical incident.
12. Extract Cart (depends on: 8, 10, 11)
Extracts the cart, which is stateful and sits directly in front of checkout. It is done before pricing and checkout because both need a stable cart boundary to call.
- Build the Cart service on Redis for session and line-item state, validating products and inventory through service calls rather than database joins.
- Make every cart operation idempotent, because a retried add or remove during a peak must not duplicate a line item.
- Keep the cart tables in the monolith as a read-only projection fed by events, for rollback and for the not-yet-migrated back-office screens.
- Ramp traffic while monitoring cart abandonment rate as the business metric, since cart latency shows up as lost revenue rather than as errors.
- Exercise anonymous and authenticated carts separately; they follow different paths and fail in different ways.
- Land this cut in an open window with a full four-week soak before the freeze.
13. Extract Pricing and Promotions as an unchanged black box (depends on: 5, 6, 7)
Extracts the 200,000-line pricing module without rewriting it. The rules are not understood by anyone, so they are wrapped and characterized rather than reverse-engineered. Rule decomposition, documentation and a DSL are explicitly out of scope for these twelve months.
- Build a golden master corpus from at least a million real historical pricing requests and their recorded outputs, covering all 8 countries, 3 currencies and 4 languages, plus every promotion type that can be discovered.
- Refactor only the module's dependencies: pricing must obtain customer, product and inventory data through interfaces rather than direct database access, so it can be lifted out.
- Move the pricing code into its own service unchanged, owning its tables after cutover, and expose a single decision API.
- Run it in shadow mode for at least four weeks against live traffic, comparing every computed price with the monolith. Any divergence blocks the ramp.
- Cut over behind a flag with per-country ramps, since a pricing error is a financial and legal exposure rather than a technical incident.
- Keep the in-monolith evaluator available and warm as the rollback path for at least one full peak after cutover.
- State in writing that rule decomposition is deferred to a follow-up program, so it does not creep back into this one.
14. Extract Payment under a stricter regime than anything else (depends on: 5, 6, 7)
Extracts payment processing, where mistakes are irreversible and regulatory. Payment is done before checkout orchestration, because checkout cannot be decomposed without a payment boundary already in place.
- Build the Payment service owning the integration with the three providers, including tokenization, authorisation, capture, refund and provider webhooks.
- Reduce PCI scope rather than expand it: no raw card data at rest in the new service, credentials in secrets management, no card data in logs or traces.
- Make every payment operation idempotent with explicit idempotency keys, because retries at peak are normal and double charges are not recoverable.
- Cut over provider by provider rather than all three at once, starting with the lowest-volume provider.
- Run the golden master across all decline, timeout, partial-authorisation and refund scenarios, and rehearse the fallback to the monolith's direct provider integration.
- Verify fraud detection and 3-D Secure paths explicitly, since they are usually the least covered and the most visible when they break.
- Land this cut early in an open window so it soaks well before the freeze.
15. Extract Order Management with an explicit state machine (depends on: 9, 10, 13, 14)
Extracts order management as the record of truth for the order lifecycle, after the services it depends on exist and are stable.
- Build the Order service with its own database and an explicit order state machine that validates every transition.
- Introduce event sourcing for order status so the audit trail satisfies regulators and fulfilment teams, and so state can be rebuilt after an incident.
- Consume events from payment, inventory and returns rather than polling or joining.
- Cut over reads first for the five teams that query orders, then writes, keeping the monolith's order tables as a reverse-CDC projection.
- Reconcile order counts and monetary totals hourly against the monolith throughout the transition. A monetary mismatch is an immediate rollback, not a ticket.
- Load-test concurrent order state transitions at peak, since the state machine becomes the new serialisation point.
16. Compose Checkout from independent services using a saga (depends on: 12, 13, 14, 15)
The highest-risk cut in the program, deliberately placed last among the transactional work and only after the components it orchestrates are individually proven.
- Build an orchestrating Checkout service that performs: cart validation, price computation, inventory reservation, payment authorisation, order creation.
- Implement compensating actions for every step: a failed authorisation releases the inventory reservation; a failed order creation voids the authorisation.
- Require idempotency keys end to end so a retried checkout cannot double-charge or double-reserve.
- Handle timeouts explicitly, including the peak case where inventory or pricing is slow. The saga must fail safe to a retryable state, never to a half-committed order.
- Mirror live checkout traffic to the new orchestration and compare full outcomes, including order totals and reservations, before any live traffic.
- Ramp live traffic during an open window only, and keep the monolith's checkout path fully functional and warm for rollback until it has survived a peak.
- Hold the six-week peak-readiness gate before this ramp and treat a failed gate as a stop, not a delay.
17. Migrate back-office, storefront and mobile clients off the monolith database (depends on: 16)
Moves the clients and the 300 back-office users onto the service APIs. Until this happens, the monolith's database remains a dependency even where the logic has already moved.
- Refactor back-office screens to consume service APIs through the gateway, replacing direct SQL access table by table, starting with orders and customers.
- Add aggregation endpoints where a screen needs several services, plus a short-lived cache so 300 staff do not multiply load on the new services.
- Update the server-rendered storefront to call service APIs while keeping the existing rendering path working behind a flag, so a rendering regression is a flag flip rather than a rollback.
- Point the mobile app at the gateway for migrated endpoints while keeping the old endpoints alive for un-updated app versions, since users do not upgrade on your schedule.
- Publish API versioning rules and deprecation windows so teams can change their services without coordinating with client releases.
- Load-test back-office behaviour with 300 concurrent staff on top of peak storefront traffic, since the two now share services.
18. Decommission the monolith core and harden for the second peak (depends on: 17)
Removes what is left of the monolith and proves the new architecture survives a peak. This step is as much about proving the state is coherent as about deleting code.
- Delete dead code and dropped tables module by module, only after a module has run a full peak or four clean weeks, whichever is longer.
- Keep read-only access to the old database for a defined period for historical and regulatory queries, then archive and decommission it.
- Replace the monolith's remaining cross-module reads with service calls or event-fed projections. The monolith should now be a small set of modules, or nothing at all.
- Re-run the full 12x load test against the new topology across all 8 countries, 3 currencies and 4 languages, and tune autoscaling, connection pools and broker partitions from the results.
- Run chaos game days: kill each service in turn and confirm the storefront degrades gracefully rather than failing completely.
- Confirm the peak-readiness gate before the second peak and publish its evidence. A failed gate defers remaining work rather than risking the peak.
- Write the exit report: final service boundaries, data ownership, runbooks, SLO history, the scope-ladder rung actually reached, and the list of work explicitly deferred to a follow-up program.
Previous Proposal 3 (ID: 10bf57da-bf5a-4286-93d2-7a544776a748, Agent: qwen3.8-flash_refine_3 - YOUR OWN previous proposal, LLM: alibaba/qwen3.8-flash):
Estimated Complexity: high
Success Metrics: - **Zero Downtime**: 100% availability maintained throughout the 12-month migration, excluding planned maintenance windows.
- **Rollback Speed**: Every service deployment is reversible in < 10 minutes via automated traffic switching at the Gateway.
- **Peak Performance**: The new architecture sustains 12x baseline load (480k orders/day) with < 200ms P95 latency for Checkout.
- **Data Integrity**: Zero discrepancies between pricing calculations of the old monolith and the new Pricing Service across 1 million replayed requests.
- **Independence**: Teams successfully deploy their services on a weekly cadence without coordinating with the monolith's bi-weekly release.
Steps (12):
1. Mobilization and Strategic Freeze Planning
Establish the governance and safety constraints for the migration. This step defines the 'no-touch' windows around peak seasons (January and July) and sets up the steering committee to manage the complexity of a 2M LOC codebase.
- **Team Alignment**: Reorganize the 5 teams into 'Service-First' pods. Each pod owns a target service extraction alongside their monolith maintenance duties.
- **Risk Framework**: Define strict 'Freeze Windows' (e.g., Dec 15–Jan 15, June 15–July 15) where no architectural changes are permitted, only bug fixes.
- **Dependency Mapping**: Create a 'Coupling Heatmap' identifying the most entangled modules (likely Pricing and Checkout) to isolate them for later phases.
2. Target Architecture and Domain Boundaries (depends on: 1)
Perform rigorous Domain-Driven Design (DDD) to define service boundaries. Given the 2M LOC and 350 tables, abstracting the domain is critical to prevent 'distributed monolith' outcomes.
- **Strategic DDD**: Map current modules to bounded contexts (Catalogue, Pricing, Orders, Identity, Fulfillment).
- **Database Decomposition Design**: Define the target data model for each service. Explicitly list which of the 350 tables move to which service and which cross-module joins must be replaced by API calls or events.
- **Contract Definition**: Draft API contracts (OpenAPI/GraphQL) for the core services to ensure backward compatibility with the existing frontend.
3. Core Infrastructure and Observability Foundation (depends on: 1)
Build the 'platform' that allows services to exist independently. You cannot safely extract services without first having the tools to see, test, and deploy them individually.
- **Kubernetes Cluster**: Provision a production-grade K8s environment with strict namespace isolation.
- **API Gateway**: Deploy a robust API Gateway (e.g., Kong, AWS ALB) to sit in front of the monolith. This is the 'Traffic Switcher' for the Strangler Fig pattern.
- **Observability Stack**: Implement Distributed Tracing (Jaeger), Centralized Logging (ELK/Loki), and Metrics (Prometheus). You must be able to trace a request from the gateway through a new service and back to the monolith.
- **CI/CD Pipelines**: Create independent deployment pipelines for services, allowing 15-minute rollback capabilities distinct from the monolith's 2-week cycle.
4. Test Harness: 'Golden Master' Characterization (depends on: 3)
Since testing the new logic against the old logic is the primary validation method, create an automated regression suite that captures the 'current truth' of the legacy system.
- **Input Logging**: Configure the monolith to log all incoming requests (and their responses) to a secure data lake, anonymizing PII.
- **Replay Engine**: Build a tool that takes a captured legacy request, sends it to both the legacy monolith and the new service, and diffs the responses.
- **Coverage Baseline**: Establish a 100% test coverage requirement for the *interfaces* being extracted. If you extract 'Search', you must have a test for every possible search query variant currently supported.
5. Extraction 1: Catalogue and Read-Only Search (depends on: 4)
The 'Low Hanging Fruit'. Extract the read-only Catalogue and Search capabilities first. This builds confidence and proves the Strangler Fig pattern without touching transactional data.
- **New Service**: Build 'Catalogue Service' that reads from a replicated Postgres (via logical replication) or a dedicated search DB (Elasticsearch).
- **Traffic Shift**: Configure the API Gateway to route `/products` and `/search` requests to the new service.
- **Fallback**: If the service fails, the gateway should immediately reroute to the legacy monolith (circuit breaker).
- **Optimization**: Replace the nightly Lucene rebuild with real-time indexing to instantly reflect price/inventory changes.
6. Extraction 2: Customer Identity and Profile (depends on: 5)
Extract user data handling. This decouples the 'who' from the 'what' (purchases), allowing independent authentication scaling.
- **Account Service**: Move user tables (Login, Profile, Address) to a dedicated service.
- **Session Migration**: Implement a token-passing strategy where the legacy monolith trusts tokens generated by the new Identity Service.
- **Read-Through Cache**: The legacy monolith should stop querying the user table directly; instead, it fetches user details from the Identity Service via an internal REST call or cached event.
- **Rollback**: Keep a 'sync-back' script to ensure if users are created in the new service, the legacy DB knows about them during the transition period.
7. Database Decoupling: The 'Anti-Corruption' Layer (depends on: 3, 5)
The most dangerous step. Breaking the 1.2TB DB entanglement requires intercepting the stored procedures. We stop writing to the shared DB from new services.
- **CDC Implementation**: Deploy Debezium to capture Postgres Write-Ahead Logs (WAL) into Kafka. This allows new services to be notified when the monolith updates data.
- **Outbox Pattern**: Refactor the monolith code so that when it writes to the DB, it also writes a 'domain event' to an internal Outbox table, which Debezium then publishes.
- **Read-Only Replicas**: Force new services to read from read-only replicas of the legacy DB to prevent them from causing lock contention on the master.
8. Extraction 3: Inventory and Fulfillment Interface (depends on: 7)
Move the inventory logic out. This separates the 'Stock' truth from the 'Order' truth, preparing for the complex checkout.
- **Inventory Service**: Create a service to hold the 'Single Source of Truth' for current stock levels.
- **Legacy Integration**: The monolith's checkout flow must now ask the Inventory Service to 'Reserve Stock' before processing payment.
- **Warehouse Sync**: Move the 15-minute file exchange logic into this service, isolating the legacy code from warehouse connectivity issues.
- **Concurrency Handling**: Implement optimistic locking in this service to handle high-concurrency 'reserve' requests during sales.
9. Extraction 4: Pricing and Promotions (The 'Black Box') (depends on: 8)
Extract the 200,000 LOC pricing engine. Do not rewrite the logic yet; wrap it. This is a 'Strangler Fig' step, not a refactoring step.
- **Encapsulation**: Move the existing pricing code (and its dependencies) into a new Spring Boot project called 'Pricing Service'.
- **Dependency Injection**: Replace direct DB access within the pricing logic with interfaces that call the Catalogue and Customer services via API.
- **Performance Parity**: Ensure the latency added by moving pricing to a separate network call is negligible (<50ms). Cache aggressively at the service level.
- **Validation**: Use the Golden Master (S4) to replay all historical orders and verify the new service returns the exact same price down to the cent.
10. Extraction 5: Checkout Orchestrator (Saga Pattern) (depends on: 9)
Replace the monolithic transaction with a distributed saga. This is the final piece of the transactional flow.
- **Orchestrator**: Build a lightweight service that coordinates the 'Checkout' process.
- **Saga Logic**: When an order is placed: 1. Call Pricing Service. 2. Call Inventory Service (Reserve). 3. Call Payment Gateway (External). 4. Call Order Service (Create).
- **Compensation**: If step 4 fails, the Orchestrator triggers 'Cancel Reserve' on the Inventory Service and 'Void' on the Payment Gateway.
- **Legacy Cutoff**: The monolith's 'Checkout' screen is replaced by a frontend form that calls this Orchestrator API.
11. Final Monolith Decomposition and Clean-up (depends on: 10)
At this stage, the monolith is hollowed out, containing mostly code that is called by the new services or legacy admin functions.
- **Admin Panel**: Move back-office functionality (Order management, Refunds) into a 'Management Service' that reads from the new event streams.
- **Code Deletion**: Delete the code for the extracted domains (Pricing, Search, Cart) from the monolith repository to enforce boundaries.
- **Database Cleanup**: Drop the tables owned by new services from the legacy monolith database.
- **Performance Tuning**: Optimize the remaining monolith for the only things it does: serving legacy redirects and perhaps a few 'orphaned' modules.
12. Peak Season Stress Test and Handover (depends on: 11)
Prepare for the high-volume events in Jan/July. Validate the new architecture holds under pressure.
- **Chaos Engineering**: Randomly kill the Search or Inventory services and verify the site degrades gracefully (e.g., 'Search temporarily unavailable') without crashing the checkout.
- **Load Testing**: Simulate 12x peak traffic using tools like Gatling/JMeter against the new APIs.
- **Runbooks**: Finalize operational playbooks for every team. Who owns what? How to restart a dead service? How to fallback to the monolith if the database fails?
Please, considering the previous proposals as ideas that could be considered, focus on the main objective and generate an IMPROVED proposal or a completely DIFFERENT perspective if you deem it appropriate. Only if you consider any of them is amazing and impossible to improve, answer with the same proposal.
The plan has these parts:
- "steps": the list of steps, each with "step_id" (a short label unique within this proposal, such as S1, S2, S3), "title" (a short, descriptive title), "description" (what the step does and how, in Markdown: a short opening paragraph and then, if there are several concrete things to say, a bullet list) and "dependencies" (the step_ids of the other steps of THIS proposal that must be completed first; empty if none).
- "estimated_complexity": "low", "medium" or "high".
- "success_metrics": clear and measurable success metrics, one per line as a bullet list.
Think deeply about the problem, considering all aspects and implications. Develop a comprehensive understanding of what needs to be done to achieve the objective, then produce the plan.
{"steps": [{"step_id": "S1", "title": "Program Governance, Peak Calendar, and Scope Ladder", "description": "Establish the binding constraints of the program before any technical work begins. The calendar dictates that the January and July sales peaks are immovable objects; therefore, all migration steps must be scheduled around them.", "dependencies": []}, {"step_id": "S2", "title": "Platform Foundation: Kubernetes, Gateway, and Observability", "description": "Deploy the infrastructure layer required to run services independently and observe traffic flow. This includes a Kubernetes cluster for workloads, an API Gateway as the central routing control point, and a full observability stack (Tracing, Metrics, Logs). The Gateway is the primary mechanism for rollback via traffic shifting.", "dependencies": ["S1"]}, {"step_id": "S3", "title": "Data Foundation: CDC, Outbox Pattern, and Transactional Events", "description": "Implement Change Data Capture (Debezium) and a Transactional Outbox pattern in the monolith. This creates the event backbone required for eventual consistency and allows new services to subscribe to monolith changes without touching the legacy code logic. This step runs in parallel with platform setup.", "dependencies": ["S1", "S2"]}, {"step_id": "S4", "title": "Architectural Decoupling: Table Ownership and Anti-Corruption Layer", "description": "Define strict ownership for the 350 tables and implement an Anti-Corruption Layer (ACL) to intercept cross-module dependencies. This involves creating separate database schemas or logical boundaries for high-coupling areas like Orders and Catalogue to prepare for physical separation.", "dependencies": ["S2"]}, {"step_id": "S5", "title": "Characterization Test Harness: The Golden Master", "description": "Build a replay engine and capture a 'Golden Master' corpus of production traffic. This automated test suite records request/response pairs from the monolith, creating a baseline for validation. This is critical for the Pricing module and high-traffic endpoints where refactoring is impossible.", "dependencies": ["S2", "S3"]}, {"step_id": "S6", "title": "First Extraction Pilot: Catalogue and Search (Read-Heavy)", "description": "Extract the Catalogue and Search services. These are low-risk (read-heavy) and validate the strangler fig pattern. Implement real-time search indexing via CDC events, replacing the nightly Lucene rebuild. Use the Golden Master to verify product data and search results match the monolith.", "dependencies": ["S3", "S4", "S5"]}, {"step_id": "S7", "title": "Second Extraction: Inventory Synchronization", "description": "Extract Inventory management, specifically handling the integration with the external warehouse system (15-minute sync). This removes a critical dependency from the monolith and enables real-time stock visibility. The service acts as the single source of truth for stock levels.", "dependencies": ["S3", "S5"]}, {"step_id": "S8", "title": "Third Extraction: Customer Profile and Identity", "description": "Extract Customer Accounts and Profile management. Move authentication logic and customer data ownership to a dedicated service. Ensure the Mobile App and Storefront can authenticate against the new service while maintaining session compatibility via JWT or shared session state.", "dependencies": ["S3", "S4"]}, {"step_id": "S9", "title": "Pricing Module Stabilization: Black Box Extraction", "description": "Extract the 200,000 LOC Pricing and Promotions module as a 'Black Box' service. Do not refactor the logic; wrap it. Use the Golden Master to validate 100% accuracy across all 8 countries and complex promotion rules. This step is strictly scheduled outside of any peak season.", "dependencies": ["S5"]}, {"step_id": "S10", "title": "Core Transactional Extraction: Orders and Order Management", "description": "Extract the Order Management domain, including order creation, state machines, and lifecycle tracking. This service acts as the consumer of events from Inventory, Pricing, and Customer services. It replaces the monolith's direct order processing logic.", "dependencies": ["S6", "S7", "S8", "S9"]}, {"step_id": "S11", "title": "Checkout Orchestration and Saga Implementation", "description": "Implement the Checkout Service, acting as the orchestrator (Saga) for the payment process. It coordinates the distributed transaction across Cart, Pricing, Inventory, and Payments. It handles compensating transactions (e.g., releasing inventory on payment failure) to ensure data consistency.", "dependencies": ["S7", "S9", "S10"]}, {"step_id": "S12", "title": "Payment Provider Integration Service", "description": "Extract the logic responsible for connecting to the three payment providers. This service handles authorization, capture, and refunds. By isolating this, the monolith no longer holds sensitive payment processing logic, reducing PCI scope and coupling.", "dependencies": ["S10", "S11"]}, {"step_id": "S13", "title": "Return and Refund Workflow Extraction", "description": "Extract the Returns and Refunds logic. This service consumes order events to trigger return workflows, updates inventory, and requests refunds from the Payment Service. This completes the reverse logistics capability as a microservice.", "dependencies": ["S10", "S12"]}, {"step_id": "S14", "title": "Legacy Monolith Decommissioning: Strangler Finish", "description": "Remove the extracted logic from the monolith. The monolith is now a legacy shell containing only the storefront rendering layer (which delegates to APIs) and potentially the Back-Office (if not yet migrated). This step involves rigorous cleanup of unused code and database tables.", "dependencies": ["S10", "S11", "S12", "S13"]}, {"step_id": "S15", "title": "Back-Office Migration and Staff Tooling", "description": "Migrate the Back-Office (300 staff users) to use the new service APIs. This may involve a dedicated BFF (Backend for Frontend) service that aggregates data from Orders, Customers, and Inventory for the staff UI, replacing direct database joins in the monolith.", "dependencies": ["S14"]}, {"step_id": "S16", "title": "Operational Handover and Autonomous Team Setup", "description": "Finalize team ownership. Each of the five teams is assigned to specific services (e.g., Team A owns Inventory and Search, Team B owns Orders and Checkout). Transfer on-call rotations and disaster recovery runbooks to the new services.", "dependencies": ["S15"]}], "estimated_complexity": "high", "success_metrics": "1. Zero unplanned downtime during the 12-month migration and subsequent peaks.\n2. Peak season (Jan/Jul) capacity maintained at 12x baseline with no performance degradation in checkout flows.\n3. 100% of Pricing and Promotion transactions match the Golden Master characterization tests post-extraction.\n4. Five teams deploying independently at least once per week without coordination conflicts.\n5. All monolith-to-service data synchronization latency under 2 seconds (near real-time).\n6. Database size reduced by >40% through extraction and cleanup of legacy unused tables.\n7. Search index refresh time reduced from 24 hours (nightly) to < 1 minute (real-time)."}Votes
The calls of the vote
The votes
| Voter | Model | Voted for | Justification | Usage | Raw |
|---|---|---|---|---|---|
| claudeHaiku4.5_voter_1 | claudeHaiku4.5 · anthropic/claude-haiku-4-5 |
Proposal A · claudeHaiku4.5_refine_1 winner | Proposal 1 is the most complete and rigorous plan. It explicitly makes the calendar a binding constraint (Step 1), defines hard freeze windows and peak-readiness gates before each risk, structures work into six rungs with deliberate stop points to prevent mid-increment slippage, includes 18+ success metrics covering all aspects (business outcomes, technical precision, rollback verification, team autonomy), details 20 comprehensive steps with explicit dependencies, and includes mandatory game-day rehearsals and chaos testing for every extraction. Most critically for the stated objective, it fully addresses how to preserve peak-season capacity by building peak-readiness gates six weeks before peaks, defining clear rollback procedures for every step, and ensuring soak periods of at least four weeks before freezes. Proposals 2 and 3 both have merit, but Proposal 2 defers checkout saga extraction beyond the 12-month window, and Proposal 3 conspicuously omits explicit freeze windows and peak-readiness gates despite the brief stating the calendar is a 'binding constraint'—a disqualifying gap for a migration where January and July sales 'must not be put at risk.' |
20.8k in · 3.1k out · 47 s | show[SYSTEM]
You are an expert and objective evaluator of project plan proposals.
Your task is to select the BEST proposal based on criteria of completeness, clarity, and alignment with the main objective.
Use your internal reasoning processes to thoroughly analyze each proposal, considering all aspects and implications.
Take as much time and space as you need to evaluate each proposal in depth before making your decision.
Every text field you write will be read by a busy person, so write for them: short sentences, one idea each, in short paragraphs. Text fields accept Markdown: separate paragraphs with a blank line, use a bullet list when you enumerate things and plain paragraphs when you explain or argue, and bold at most one key phrase per paragraph. A text of more than three sentences must be split into paragraphs; never deliver a single unbroken block of text.
[HUMAN]
Main Objective: "A mid-size European fashion retailer runs its e-commerce on a 10-year-old monolith: Java 8 / Spring, about 2 million lines, one PostgreSQL database of 1.2 TB with 350 tables and heavy use of stored procedures and cross-module joins. It serves 8 countries, 3 currencies and 4 languages, with about 40,000 orders a day and peaks of 12x during sales. The monolith contains: the storefront (server-rendered, plus a separate mobile app hitting the same endpoints), catalogue and search (a Lucene index rebuilt nightly), pricing and promotions (the most complex module, 200,000 lines, with country-specific rules nobody fully understands), cart and checkout with three payment providers, order management, inventory synchronised every 15 minutes with the warehouse system via file exchange, customer accounts and loyalty, returns, and a back-office used by 300 staff. Deployments happen every two weeks as a single artefact with a 30-minute maintenance window; test coverage is 25% and mostly unit tests. Five teams of 8 developers, each organised around a business area but all committing to the same repository.
Plan the migration to independently deployable services over 12 months with no feature freeze, no unplanned downtime and the ability to roll back every step, preserving the peak-season capacity (sales in January and July must not be put at risk)."
Proposals to Evaluate:
--- PROPOSAL 1 ---
Proposal ID: eaa6af3c-28c3-480e-b9b1-be2c22215422
Content:
Estimated Complexity: high
Success Metrics:
- **Zero unplanned downtime**: 100% availability throughout 12-month migration (excluding planned 30-min blue-green deployments); no production incidents attributable to migration architecture
- **Peak seasons protected**: January and July peaks (480k orders/day) sustain zero degradation caused by migration; checkout p99 ≤ 5 seconds, payment authorization ≤ 2 seconds, error rate ≤ 0.5%, no queue backlog > 5 minutes
- **Independent deployability**: All eight services independently deployable by month 12; each team releases on own cadence (weekly or faster) with zero cross-team deployment coordination; 100% of service releases verified rollback-capable in < 30 minutes
- **Rollback-proven**: Every production increment has rehearsed, documented, tested rollback path (expand/contract migrations, feature flags, reverse CDC); monthly chaos game days validate rollback procedures; zero increments reach production without passing rollback gate
- **Data consistency**: Hourly reconciliation shows < 0.001% row-count and checksum discrepancy between service databases and monolith (pre-decommissioning); zero business-invariant violations (no duplicate orders, no lost payments, no inventory oversells)
- **Pricing correctness**: 100% agreement between new Pricing service and golden-master corpus across 1M+ historical requests covering all 8 countries, 3 currencies, 4 languages, all promotion types; zero pricing errors post-cutover
- **Search freshness**: Product availability reflects in search within < 60 seconds of inventory change (vs. nightly rebuild); search latency p95 unchanged or improved at peak load
- **Warehouse sync improvement**: Inventory synchronization lag reduced from 15 minutes to < 2 minutes end-to-end; 100% of daily warehouse updates processed; no missed sync cycles during migration
- **Payment processing**: Zero regressions with all three payment providers; fraud detection active and effective; PCI-DSS compliance maintained; idempotency prevents duplicate charges; payment success rate ≥ 99.5% at peak
- **Back-office operations unaffected**: All 300 staff seamlessly using service APIs; service aggregation endpoints maintain p95 latency ≤ 500 ms; bulk operations (refunds, order status updates) complete within SLA
- **Test coverage for services**: All newly written service code reaches 80%+ line coverage; golden master validates 100% of public API contracts before production traffic; contract tests (Pact) prevent breaking changes between services
- **Peak-readiness gate passed**: Six weeks before each peak (mid-November, mid-May), gate published showing 12x load test results, capacity headroom, rollback rehearsal duration, and SLO status; failed gate defers work; evidence published publicly
- **Team independence by month 12**: Five teams deployed independently; each owns service codebase, pipeline, database schema, on-call rotation, SLOs; no cross-team pull requests blocking releases; internal developer platform (golden-path templates, self-service deployments) adopted by all teams
- **Scope ladder completed**: Rungs 1–6 reached by month 12 (or deliberately stopped at rung boundary with documented justification); all services proven at peak; monolith reduced to < 5% or decommissioned
- **Calendar adherence**: No major extractions or refactors during freeze windows (Dec 1–Jan 15, June 1–July 15); all production increments land in open windows with minimum 4-week soak before freeze; timeline published and adhered to
- **Event-driven architecture validated**: Kafka message broker handles 480k+ messages/day at peak; no message loss, no ordering violations; outbox pattern ensures every domain event persists atomically
- **Fallback capacity maintained**: Monolith rollback path kept warm and functional (receiving live traffic or ready-to-receive via feature flag) until each service survives one full peak; no service extracted without proven rollback capability
Steps (20):
1. Program Setup, Scope Ladder, Organizational Model, and Peak-Safe Calendar
Establishes the governance framework and constraints that all later work obeys. The calendar is the binding constraint—January and July peaks must not be put at risk—so it is decided first, before any technical choices.
**Inception and Baselines**: Run a two-week inception to establish current state: build time, deployment lead time, change failure rate, MTTR per team, module-change frequency, database load profiles (all measurable, not asserted).
**Calendar and Freeze Windows**: Declare hard freezes from December 1–January 15 and June 1–July 15; only rollback-enabling and hardening changes allowed during freezes. Confirm two open delivery windows per year (February–May and August–November); all migration work must fit these windows. No change on checkout path lands within four weeks of a freeze.
**Scope Ladder**: Define ranked rungs 1–6 that deliver the core objective; rungs 7+ are optional. Slippage means stopping at a rung boundary, never mid-increment. Rungs: 1. Platform ready. 2. Search extracted and proven. 3. Returns and Inventory proven at low stakes. 4. Payment and Orders stable. 5. Checkout orchestration live and soaking. 6. Back-office migrated, monolith core reduced.
**Organizational Model**: Define service-aligned teams (Search, Orders, Inventory, Payments, Customer, Fulfillment) with clear ownership, on-call rotations, and SLOs per service. Each team owns codebase, pipeline, database schema, and incidents by month 6. Transition plan: teams split duties (monolith maintenance + service) until month 3, then shift to service-primary by month 6.
**Rollback Charter**: Every increment ships an expand/contract database change, a feature-flag kill switch, and a recorded game-day rehearsal. No go-live without tested rollback in < 30 minutes.
**Peak-Readiness Gate**: Define gate to run six weeks before each peak (mid-November, mid-May): 12x load test, capacity headroom check, rollback rehearsal, error-budget review. Gate is pass/fail; failed gate defers work to next window.
**Capacity Budget**: Allocate 40–50% of five teams' capacity for migration; staff scope ladder to fit capacity, not to fill the year. Create migration enablement squad of six rotating engineers to own platform, shared cuts, and risky data work.
2. Executable Architecture Map, Table Ownership, and Boundary Enforcement (depends on: 1)
Produces an architecture map that the build itself enforces. Five teams in one repo will silently re-couple anything separated if not policed, so enforcement is embedded in the map.
**Real Coupling via Tracing**: Instrument monolith with distributed tracing; let it run four weeks to capture real call paths—static imports miss true coupling.
**Table Ownership Matrix**: Parse every SQL statement, ORM mapping, and stored procedure; cross-check against database query logs. Build table-to-module and query-to-module map. Assign every 350 table to exactly one owning module; tables nobody can own are 'contested' and scheduled into data work (Step 7).
**Scoring and Extraction Sequence**: Score each candidate service on coupling, transactional risk, change frequency, and peak-path criticality. This ranking (not intuition) drives extraction order.
**Enforcement via Automation**: Add ArchUnit rules to CI to fail builds on new cross-module Java dependencies (existing violations frozen in baseline that may only shrink). Add SQL linter to CI to fail on cross-module joins and cross-module writes (same shrinking baseline). Violations tracked weekly in architecture review.
**Stored Procedure Audit**: Inventory all stored procedures; attribute to owning module; plan move into module code or leave as module-private function. No stored procedure may touch two modules' tables post-extraction.
**Architecture Decision Records**: Publish target service list, owning team per service, and reasoning as ADRs.
**Mid-Program Review**: Hold review at month 6 to re-rank scope ladder using what the map actually revealed. This is the one planned re-planning point of the program.
3. Delivery Platform: Per-Service Pipelines, Gateway, Feature Flags, and Environments (depends on: 1, 2)
Builds the delivery and traffic machinery that makes every later step reversible. No service is extracted until its team can deploy, flag, and route independently.
**Kubernetes and Namespaces**: Extend platform on Kubernetes (or existing container platform) with one namespace per service, quotas, and autoscaling sized for 12x peak (480k orders/day). Establish dev/staging/prod with strict resource isolation.
**API Gateway**: Deploy API gateway (Kong, AWS ALB) in front of monolith as strangler entry point. Storefront, mobile app, and back-office traffic flow through gateway from day one, even while routing everything to monolith. Gateway enforces rate limiting, bulkheads, timeouts, and circuit breakers.
**Feature-Flag Service**: Deploy centralized feature-flag system (LaunchDarkly, Unleash). Require every new call path to be flag-guarded. Flags are the primary rollback instrument; changes to traffic routing require no code deployment.
**Per-Module CI/CD Pipeline**: Give every module its own independent CI/CD pipeline and environment. Monolith keeps current pipeline for hotfixes until Step 5 replaces it. Pipeline includes automated security scanning, performance baselines, and contract-test gates.
**Secrets and Configuration**: Introduce secrets management (Vault) and per-environment configuration. Behavioral changes require no monolith redeploy.
**Golden-Path Templates**: Define reusable templates for new services: build layout, Dockerfile, pipeline stages, observability instrumentation, health checks, feature-flag integration, database migration tool. Extraction starts from template, not blank page.
**Permanent Environments**: Reserve two full-size environments: (1) production-like soak environment for multi-week stability validation, (2) load-test environment capable of 12x traffic generation against production-shaped data (8 countries, 3 currencies, 4 languages, realistic product catalog).
4. Observability, Business SLOs, Error Budgets, and Automated Rollback Controller (depends on: 3)
Makes the system observable so canaries are judged automatically and reverted without human guessing. This is the prerequisite for rollback promises in all later steps.
**Observability Foundation**: Deploy centralized logging (ELK/Loki), metrics (Prometheus/Grafana), and distributed tracing (Jaeger) with trace correlation working across gateway, monolith, and every new service from day one.
**Blind-Spot Instrumentation**: Instrument monolith's unmeasured aspects: query latency by module, connection-pool saturation, Lucene rebuild duration, warehouse file-exchange lag, stored procedure execution time, lock contention.
**Business SLOs**: Define SLOs on business outcomes, not infrastructure:
- Checkout success rate ≥ 99.5%
- Order confirmation latency p99 ≤ 5 seconds at baseline (40k orders/day) and peak (480k orders/day)
- Search result latency p95 ≤ 1 second
- Payment authorization latency ≤ 2 seconds
- Price computation latency ≤ 200 ms
- Warehouse sync freshness ≤ 2 minutes end-to-end (vs. current 15 minutes)
- Cross-module data consistency: hourly reconciliation shows < 0.001% row-count discrepancy
**Error Budget and Rollback Policy**: Attach error budget to each SLO. When a service burns budget (or latency diverges > threshold during canary), its rollout stops automatically and flags revert without negotiation. Document policy explicitly; use during peaks without exception.
**Automated Rollback Controller**: Build system that monitors error rate and latency divergence during canary. On breach, gateway shifts traffic back and flags disable automatically. Fallback requires no human intervention. Test this automation in monthly game days.
**Dashboards**: Create per-service dashboards readable by tired engineers at 3 AM (traffic, errors, latency p50/p95/p99, database load). Create program dashboard showing progress against scope ladder, rung by rung.
5. Pricing Module: Rules Catalog and Golden-Master Characterization (Parallel with Data Platform) (depends on: 1, 2)
Catalog the 200k LOC pricing engine behavior before any extraction attempt. This is the foundational risk mitigation for the most complex module; it runs in parallel with data platform work (Step 7) because it is independent of infrastructure.
**Rules Discovery and Documentation**: Analyze and document all pricing rules in scope: country-specific logic (8 countries), currency handling (3 currencies), promotional rules, seasonal pricing, bulk discounts, loyalty point applications, regional variations. Create a living rules inventory.
**Historical Request Corpus**: Capture at least 1 million real historical pricing requests from production logs, covering all 8 countries, 3 currencies, 4 languages, all promotion types discoverable, edge cases, peak-season variations. Record exact inputs and outputs.
**Golden-Master Characterization Suite**: Build automated harness to replay corpus against monolith, capturing deterministic responses. This suite is the 'golden master': any new pricing service must match 100% of outputs. Suite becomes the automated gate for pricing extraction (Step 14).
**Test Data Expansion**: Supplement historical data with synthetic edge cases: multi-currency conversions, minimum purchase thresholds, conflicting promotions, time-based seasonal rules, inventory-driven pricing, customer-segment overrides.
**Dependency Mapping**: Explicitly document which customer attributes, product attributes, inventory levels, time-based factors, and external parameters affect pricing. Identify all cross-module dependencies that pricing currently reads from monolith (e.g., customer loyalty status from Customer module, product hierarchy from Catalogue module).
**Baseline Validation**: Run golden master against monolith to establish baseline passing rate. Document any non-deterministic behavior or race conditions found. This baseline is locked; no drift allowed during migration.
**CI Gate Definition**: Define hard rule: pricing service extraction cannot proceed until characterization tests pass 100% against both monolith and new service. Any divergence blocks ramp. This gate is not negotiable.
6. Seam-Level Verification: Golden Master, Contracts, Shadow Diffing, and Reconciliation (depends on: 2, 3)
Replaces impossible goal of blanket test coverage with verification exactly at the cut point. A 2M-line monolith cannot reach 70% coverage in a year; a service boundary can be verified to very high standard in weeks.
**Characterization Harness for All Services**: Build framework to record real production requests (anonymizing PII) and replay against monolith. Capture full responses as golden master. Every extracted service must pass golden master on its public API before taking live traffic. Output a diff report, not pass/fail.
**Consumer-Driven Contracts (Pact)**: Require contracts between monolith and each new service, and between services themselves. A change on one side breaks a build instead of waiting for production. Contracts versioned; breaking changes trigger explicit communication plan.
**Shadow Traffic and Response Diffing**: Mirror live requests to new service; compare responses field by field (not just status codes). Measure divergence rate continuously. Gate traffic ramp on divergence < 0.01% for 48 hours.
**Per-Module Data Reconciliation**: Build data reconciliation as first-class test, not afterthought. Compare row counts, checksums, and business invariants on hourly schedule. Owner assigned; alert threshold set. Reconciliation runs continuously during transition period (Stages A–C of cutover playbook).
**Synthetic Canary Transactions**: Implement real checkout, return, and search transactions executing every few minutes. Alert on functional regression before customers notice. Include multi-country, multi-currency variations.
**Explicit Non-Goal**: Do not pursue blanket line coverage of monolith. Track coverage only for newly written service code, target 80%. Seam-level verification replaces this impossible goal.
7. Data Platform: Schema Ownership, Join Elimination, CDC, Transactional Outbox, and Four-Stage Cutover Playbook (depends on: 2, 3)
The hardest and most under-specified part of most migrations. This work is independent of service extraction, so it starts in month 1 and runs in parallel. It is the foundation for reversible data transitions.
**Database-Enforced Ownership**: Assign every PostgreSQL table to exactly one module. Create one role per module, able to write only its own schema and to read others only through defined views. Database rejects cross-schema writes at the engine level, not by convention. Test this enforcement in CI.
**Stored Procedure Refactoring**: Inventory every stored procedure, attribute it to owning module. Either move logic into that module's application code or leave as module-private database function. After extraction, no stored procedure may touch two modules' tables.
**Cross-Module Join Elimination**: Eliminate cross-module joins one at a time, replacing each with an API call (preferred during cutover), an event-fed materialized read model, or a duplicated read-only projection. Track count per module; drive to zero before that module is extracted.
**Change Data Capture (CDC)**: Deploy Debezium reading PostgreSQL WAL into Kafka. This publishes monolith domain events with zero application change—lowest-risk start possible. Configure per-table CDC; test at peak load (480k events/day during 12x peak).
**Transactional Outbox Pattern**: For all new services, add outbox table. When service writes business state, it writes domain event atomically in same transaction. Outbox relay publishes to Kafka, ensuring no event loss. Implement poison-pill handling for failed publishes.
**Four-Stage Cutover Playbook (Reusable)**: Define one playbook applied identically every service extraction:
- **Stage A** (Shadow-Read): Service owns schema logically, reads from CDC into its own store, serves shadow traffic only. Monolith remains system of record; no cutover yet.
- **Stage B** (Read Cutover): Reads cut over to new service via flag. Monolith stays system of record via reverse-CDC replication. Rollback is flag flip + reconciliation pass.
- **Stage C** (Write Cutover): Writes cut over to new service. Monolith tables become read-only replicas fed by reverse CDC from service. Rollback is configuration change (flip sync direction) + reconciliation, not data restore.
- **Stage D** (Deletion): Old tables and dead code dropped only after module has survived one full peak (January or July) or four clean weeks, whichever is longer. Maintain 90-day read-only archive of old tables for regulatory retention and emergency queries.
**Reconciliation Service**: Build now (not later) so every cutover has objective consistency check. Compare row counts, business-invariant checksums, monetary totals hourly. Owner assigned; thresholds set. Mismatch is immediate rollback signal.
**Storage Migration Timeline**: New services start on existing cluster with own schemas. Physical database split (move to separate cluster) happens only once module is stable and proven at peak. This removes a critical-path blocker and allows parallelization.
8. Extract Catalogue and Search: Read-Heavy Pilot Service (depends on: 5, 6, 7)
First extraction, chosen because it is read-heavy, isolated, and carries no transactional risk. It also pays for itself: replacing nightly Lucene rebuild with real-time indexing is a visible business win that buys political cover for harder cuts.
**New Catalogue Service**: Create service owning product, category, media, and attributes tables. Build search API using Elasticsearch/OpenSearch with real-time indexing.
**CDC Feed**: Subscribe to CDC stream from monolith. ProductUpdated, PriceChanged, InventoryUpdated events trigger real-time search index refresh. Product availability reflects in search within < 60 seconds of change (vs. nightly rebuild).
**Shadow Traffic and Diff Validation**: Route requests through gateway behind feature flag. Run shadow mode: send requests to both monolith Lucene and new Search service; compare result sets field by field. Measure divergence; require < 0.01% for 48 hours before traffic ramp.
**Gradual Traffic Ramp**: 1% → 5% → 25% → 50% → 100% using feature flags and canary deployments. Rollback controller monitors latency and error rates; reverts flag if breach. Keep old Lucene index warm for two weeks post-cutover as rollback target.
**Mobile App Verification**: Verify mobile app behavior explicitly; it hits same endpoints. Test session persistence, offline search cache behavior, and app version compatibility during ramp.
**Four-Stage Playbook**: Execute Stages A–D as defined in Step 7. Stage A (shadow) lasts 1 week minimum. Stage B (read cutover) lasts 2 weeks. Stage C does not apply (reads only). Stage D (cleanup) after one peak or four weeks.
**Soak Period**: Land this extraction in open delivery window; soak at least four weeks before freeze (Dec 1 or June 1). No extraction reaches production less than four weeks before a freeze.
9. Extract Returns: Low-Stakes Proof of Four-Stage Playbook (depends on: 5, 6, 7)
Second extraction and first write-path proof. Returns is chosen because it is off peak-critical path, has modest coupling, and exercises full four-stage playbook at low risk. Primary output is a proven, reusable procedure, not just one service.
**Returns Service**: Build with own schema. Consume order and customer events rather than joining their tables. Implement return state machine: Requested → Approved → Shipped → Received → Refunded.
**Full Four-Stage Execution**: Apply Stages A–D end-to-end with explicit recorded game day validating each stage rollback path. Stage A (shadow reads) for 1 week. Stage B (read cutover) for 2 weeks. Stage C (write cutover) with reverse CDC. Stage D (cleanup) after one peak or four weeks.
**Rollback Rehearsal**: Before write cutover, execute full game day: simulate service failure mid-cutover, trigger rollback (reverse CDC, flag flip, reconciliation), verify all data consistent, re-run golden master, confirm back-office queries still work. Record this session; play back monthly.
**Back-Office Screens**: Keep back-office returns screens on monolith for now (staff workflow untouched). Returns service is API-only; back-office integration comes later (Step 18).
**Friction Point Capture**: Record every operational friction, process gap, and test hole discovered during extraction. Update playbook from learnings. This step is as much about process validation as about extracting Returns.
**Soak and Timing**: Execute in open window; soak returns service for minimum four weeks before any freeze. Gate to proceeding to Inventory (Step 10) is successful four-week soak with zero rollbacks and full reconciliation agreement.
10. Extract Inventory: Warehouse Sync Improvement and Reservation Semantics (depends on: 5, 6, 7)
Removes one of sharpest coupling points (15-minute file-exchange lag) and unblocks checkout work. Inventory runs in parallel with returns because it couples monolith to external warehouse system, not to other modules.
**Inventory Service**: Ingest warehouse feed directly (SFTP/API) instead of monolith polling. Design reservation semantics now: Reserve (place hold), Confirm (finalize after order), Release (cancel reservation on timeout/failure), with explicit timeout windows. Own stock levels and reservations per product per location.
**Parallel Feeds During Transition**: Run new ingest in parallel with legacy 15-minute feed. Reconcile hourly until both agree. This validates the new ingest does not miss updates or duplicate changes.
**Monolith Inventory Tables as Projection**: Keep monolith's inventory tables as read-only replicas fed by CDC from new service during Stage C (write cutover). Cart and checkout continue calling monolith queries unchanged during cutover; no checkout changes yet.
**Four-Stage Execution**: Apply Stages A–D. Stage A (shadow ingests and reads) for 2 weeks (must survive two 15-minute sync windows and validate no drift). Stage B (read cutover) for 2 weeks. Stage C (write cutover) with reverse CDC. Stage D (cleanup) after one peak.
**Peak-Load Testing**: Load-test inventory ingest at 12x (400k SKU updates/day during peak). Warehouse feed schedule and sales peaks do not always align; test worst-case concurrency. Validate no reservation deadlocks, no stock over-sells.
**Cutover Order**: Inventory read cutover must complete before Cart extraction (Step 13) to avoid monolith checkout calling new Inventory service via internal API during transition.
**Soak and Gate**: Soak minimum four weeks before freeze. Gate to proceeding to Customer (Step 11) is four-week soak with zero reconciliation mismatches and warehouse feed lag improved to < 2 minutes.
11. Extract Customer Accounts and Loyalty: Conservative Authentication Strategy (depends on: 9, 10)
Extracts customer identity, profile, and loyalty programs. Authentication is deliberately placed late and guarded hardest because auth failures derail e-commerce migrations most often.
**Customer Service**: Own profile, address, and loyalty tables. Implement country-specific loyalty rules (8 countries, different point accrual rates) as data-driven rules where possible, code where not. Design API: GetCustomer, UpdateProfile, GetLoyaltyBalance, RedeemPoints, AccruePoints.
**Authentication Strategy Phase 1**: Keep authentication (login) in monolith for now. Customer service exposes only data APIs; token issuance remains monolith's responsibility. This delays risky auth cutover; less risk to peak season.
**Distributed Session Handling**: Introduce Redis-backed distributed sessions. Services can verify customer identity without querying monolith database. Implement token-validation API so services can verify bearer tokens without round-tripping to monolith.
**Data Cutover**: Execute four-stage playbook. Stage A (shadow reads) for 1 week. Stage B (read cutover) for 2 weeks. Stage C (write cutover) for new customers, address updates, loyalty accrual. Stage D (cleanup) after one peak.
**Golden Master for All Countries**: Golden master captures customer queries across all 8 countries, all 4 languages, and all loyalty-rule variations. Shadow-traffic diff must show < 0.01% divergence before read cutover.
**Mobile App Session Behavior**: Test mobile app's long-lived sessions explicitly; storefront does not hold sessions same way. Validate token refresh, session timeout, and app version compatibility during cutover.
**Loyalty Accrual Last**: Move loyalty point accrual and redemption last within this step (Stage C final substep). Loyalty error is customer-visible financial error, not technical incident; guard hardest.
**Soak and Gate**: Soak minimum four weeks. Gate to proceeding to Cart (Step 13) is successful loyalty accrual cutover with zero customer complaints and full reconciliation agreement.
12. Extract Cart: Stateful Session Service (depends on: 6, 7, 10, 11)
Extract shopping cart, which is stateful and sits directly in front of checkout. Extracted before Pricing and Checkout because both depend on stable Cart boundary.
**Cart Service on Redis**: Build on Redis (or PostgreSQL with session affinity) for session and line-item state. Validate products and inventory through service API calls rather than direct database joins. Design API: AddItem, RemoveItem, UpdateQuantity, GetCart, ApplyCoupon, ClearCart.
**Idempotent Operations**: Every cart operation is idempotent. Retried add during peak does not duplicate line item. Retried remove is safe. Implement via unique constraint on (session, sku) or idempotency-key header.
**Monolith Cart Tables as Projection**: Keep monolith's cart tables as read-only projections fed by CDC from Cart service. Back-office screens continue reading old cart tables for abandoned-cart analytics (not yet migrated to service APIs in this step).
**Four-Stage Execution**: Apply Stages A–D. Stage A (shadow reads) for 1 week. Stage B (read cutover) for 2 weeks (use feature flag; gradual ramp 10% → 50% → 100%). Stage C (write cutover to service); Stage D after one peak.
**Business Metric Monitoring**: Cart latency surfaces as lost revenue (abandonment), not just error logs. Track cart abandonment rate and add-to-cart latency as primary success metrics during ramp.
**Anonymous vs. Authenticated Carts**: Test both paths separately; they follow different session-tracking mechanisms and fail in different ways. Ensure cart persists across login boundary.
**Soak Before Freeze**: Land in open window; soak minimum four weeks before freeze (Dec 1 or June 1). Gate to proceeding to Pricing (Step 14) is four-week soak with cart abandonment rate unchanged or improved and zero lost transactions.
13. Extract Pricing as Black Box Using Golden-Master Validation (depends on: 5, 6, 7)
Extract 200k LOC pricing logic as-is without rewriting. Rules are not understood by anyone, so wrap and characterize rather than refactor. Rule decomposition deferred to follow-up program in writing.
**Wrap Without Refactor**: Move pricing code into dedicated service, unchanged. Service owns pricing tables post-cutover. Expose single decision API: ComputePrice(customerId, productId, locationId, timestamp, quantityId, loyaltyStatus) → {price, applicablePromotions, taxes, currency}.
**Dependency Injection for Reads**: Refactor pricing's dependencies so it obtains customer data via Customer service API, product data via Catalogue service API, inventory via Inventory service API. No direct cross-module database joins.
**Golden-Master Validation**: Run characterization test suite (built in Step 5) against new service. Require 100% output match on all 1M historical requests across all 8 countries, 3 currencies, 4 languages, all promotion types, edge cases. Any divergence blocks ramp; no exceptions.
**Shadow Mode Duration**: Run shadow traffic against live pricing requests for minimum four weeks, comparing every computed price with monolith. Measure divergence continuously. Divergence > 0.001% blocks ramp.
**Gradual Cutover by Country**: Cut over per-country rather than all-at-once. Start with lowest-revenue country, validate four weeks per country, then ramp to others. Per-country flags allow independent rollback.
**Rollback Path**: Keep monolith's pricing evaluator available and warm as rollback target for at least one full peak (January or July) after cutover. Maintain ability to flip back to monolith pricing via feature flag without data restore.
**Four-Stage Playbook**: Stages A–D applied to pricing tables. Stage A (shadow) 4+ weeks. Stage B (read cutover) 2 weeks per country. Stage C (write cutover) per country. Stage D (cleanup) after one full peak.
**Deferred Refactoring in Writing**: Publish decision that pricing rule decomposition, DSL, and optimization are explicitly deferred to follow-up program after this migration stabilizes. Include this in all project communications and retrospectives.
14. Extract Payment: PCI-Strict Regime and Provider-by-Provider Cutover (depends on: 5, 6, 7)
Extract payment processing with stricter regime than any other service. Mistakes are irreversible and regulatory. Extracted before checkout orchestration because checkout cannot be decomposed without payment boundary.
**Payment Service**: Own integration with three payment providers (tokenization, authorization, capture, refund, provider webhooks). Design API: AuthorizePayment(idempotencyKey, amount, currency, cardToken, customerId) → {authorizationId, status}; CapturePayment(authorizationId); RefundPayment(captureId); HandleWebhook(webhookPayload).
**PCI Scope Reduction**: No raw card data at rest in service. Card data flows directly from client to provider (tokenization); only tokens stored in Payment service. Credentials in secrets management (Vault). No card data in logs or distributed traces.
**Idempotent Operations**: Explicit idempotency-key handling. Every payment request is idempotent; retries at peak are normal and must not double-charge. Implement via idempotency-key deduplication store (Redis with TTL).
**Provider-by-Provider Cutover**: Cut over one provider at a time (start with lowest-volume provider). Stage A (shadow) 2 weeks per provider. Stage B (read cutover, not applicable). Stage C (write cutover) for each provider, maintain fallback to monolith for other providers. Test each provider's decline, timeout, 3-D Secure, and chargeback scenarios explicitly.
**Golden Master Scenarios**: Golden master covers all three providers, all decline reasons, timeouts, partial authorizations, refund scenarios, chargebacks. Shadow traffic compares full payment outcomes (authId, status, amount, timestamp) before any live provider cutover.
**Fraud Detection and 3-D Secure**: These paths are usually least-tested and most visible when broken. Test explicitly; goldne master includes fraud-decline and 3-D Secure flows. Verify fraud rules and thresholds carry over unchanged.
**Fallback Orchestration**: Monolith retains ability to handle payment directly (as fallback) until second peak after Payment service cutover. Checkout can gracefully degrade to old payment path via feature flag if new service fails.
**Four-Stage Playbook**: Stages A–D per provider. Stage C (write) is highest-risk; ensure golden master passes 100% and shadow mode shows zero divergence before each provider cutover. Gate and soak strictly: four weeks minimum before any freeze.
**Soak and Timing**: Land in open window (Feb–May or Aug–Nov). Complete all three providers' Stage C cutover by month 9 to allow checkout orchestration time to soak before freeze.
15. Extract Orders: Event-Sourced Record of Truth (depends on: 9, 13, 14)
Extract order management as authoritative record of order lifecycle. Extracted after Inventory, Pricing, and Payment exist and are stable, because Orders depends on all three.
**Orders Service**: Own order tables and order state machine. Implement explicit state transitions: Pending → Confirmed → Preparing → Shipped → Delivered, with validation blocking invalid transitions. Design API: CreateOrder(cartId, customerId, paymentAuthorizationId), GetOrder(orderId), CancelOrder(orderId), UpdateOrderStatus.
**Event Sourcing**: Record all order state changes as immutable events. Build order state from event log on demand. Audit trail satisfies regulators and fulfillment teams; state can be rebuilt after incidents. Include: OrderCreated, PaymentAuthorized, InventoryReserved, OrderConfirmed, OrderPreparing, OrderShipped, OrderDelivered, OrderCancelled.
**Event Consumption**: Consume events from Payment service (PaymentAuthorized, PaymentFailed), Inventory service (StockReserved, ReservationCancelled), and Returns service (ReturnInitiated, RefundIssued) rather than polling or joining.
**Four-Stage Playbook**: Stages A–D. Stage A (shadow) for 1 week. Stage B (read cutover) for 2 weeks, with gradual flag ramp. Five teams that query orders start reading from Orders service via API. Stage C (write cutover): new orders written to Orders service; monolith order tables become reverse-CDC read-only replicas. Stage D after one peak.
**Reconciliation: Monetary and Row-Count**: Reconcile order counts and monetary totals hourly against monolith throughout transition. Currency totals must match exactly (cent-by-cent); row count discrepancies are immediate rollback. Implement automated reconciliation query; owner assigned; threshold zero.
**Concurrent Order Transitions**: Load-test concurrent order state transitions at 480k/day peak. Order state machine becomes serialization point for distributed system; ensure no race conditions, no duplicate orders, no lost transactions.
**Soak Before Checkout**: Complete Orders cutover (Stages A–C) by month 9. Soak minimum four weeks before freeze. Gate to proceeding to Checkout (Step 16) is four-week soak with zero monetary reconciliation mismatches and zero order duplicates.
16. Extract Checkout: Distributed Saga Orchestration (Highest Risk) (depends on: 12, 13, 14, 15)
Highest-risk extraction, deliberately placed last among transactional work and only after components it orchestrates are individually proven at scale. This step composes independent services into coherent checkout flow.
**Checkout Orchestrator Service**: Build service that coordinates checkout: cart validation, price computation, inventory reservation, payment authorization, order creation. Design as explicit saga with named steps and compensating actions.
**Saga Orchestration**: Implement synchronous saga (single coordinator) or asynchronous (choreography via events), chosen based on latency testing (target checkout p99 < 5 seconds at peak). Synchronous preferred for checkout because customer waits; failure is visible. Steps:
1. Validate cart via Cart service
2. Compute price via Pricing service (cached if < 1 second old)
3. Reserve inventory via Inventory service
4. Authorize payment via Payment service
5. Create order via Orders service
**Compensating Transactions**: For every step, define compensation:
- Step 3 fails: Release inventory reservation
- Step 4 fails: Release inventory reservation, void authorization (if possible)
- Step 5 fails: Release reservation, void authorization, return payment to customer
- Step 2 recomputes and differs: Increase price, reject order; or decrease price, accept at old price (business rules decision, document explicitly)
**Idempotency End-to-End**: Checkout request includes idempotency key (unique per browser session + timestamp). Service deduplicates on this key. Retried checkout cannot double-charge or double-reserve; returns previous result.
**Timeout Handling**: Inventory reservation expires in 15 minutes (configurable). Payment authorization valid for 7 days (provider-specific). Order creation never times out; if hanging, manually investigate. Saga must fail safe to retryable state, never to half-committed order.
**Shadow Traffic Before Live**: Mirror live checkout traffic (100% of checkout requests during business hours) to new orchestration for minimum 2 weeks before any live cutover. Compare full outcomes: order ID, order total, inventory reservations, payment authorization IDs, error messages. Divergence > 0.001% blocks live cutover.
**Live Ramp During Open Window**: Ramp live traffic only during open delivery window (Feb–May or Aug–Nov). Gate and soak strictly: minimum four weeks before freeze. Keep monolith checkout path fully functional and warm (receiving live traffic via feature flag) as rollback target until Checkout service has survived one full peak.
**Peak-Readiness Gate Mandatory**: Hold six-week peak-readiness gate (Step 19) before proceeding to back-office migration (Step 18). Failed gate stops this work immediately and defers to next window.
17. Migrate Back-Office, Storefront, and Mobile Clients to Service APIs (depends on: 16)
Moves 300 back-office staff and client applications off monolith database direct access. Until this step, monolith database remains live dependency even where logic moved.
**Back-Office Screen Refactoring**: Migrate screens table by table. Replace direct SQL with service API calls through gateway. Start with orders (call Orders service), then customers (call Customer service), then inventory (call Inventory service). Build aggregation endpoints: /orders/{id}/full-details calls Orders + Payments + Inventory + Returns services, caches 30 seconds, returns unified response.
**Aggregation Endpoints and Caching**: Services are now call-chain away, not co-located. Back-office latency would suffer without caching. Implement short-lived cache (TTL 30 seconds) for frequently accessed data (customer profiles, recent orders). Graceful degradation: if one service slow, show cached data and alert staff.
**Storefront and Mobile App**: Both hit same endpoints (via gateway). Update storefront (server-rendered) to call service APIs while keeping old path functional behind feature flag; rendering regression becomes flag flip, not rollback. Mobile app points at gateway for migrated endpoints; keep old endpoints alive for un-updated app versions (users do not upgrade on schedule). Implement API versioning: v1 (legacy monolith), v2 (service APIs); clients request version in Accept header.
**API Versioning and Deprecation Windows**: Publish versioning rules: breaking changes trigger major version bump (v2 → v3). Old version supported for minimum 90 days after major release. Client teams must upgrade within window; do not force upgrade. Document deprecation timeline in API spec.
**Load Test Back-Office Concurrency**: Test 300 concurrent staff on top of peak storefront (480k orders/day). New services now carry both loads; autoscaling and database connection pools must handle burst. Simulate realistic staff queries: order searches, customer history, bulk refunds.
**Distributed Tracing for Debugging**: Every back-office request traced across services. Staff can view trace in UI; operations team can see which service was slow. Trace includes: request start, service calls, database queries, cache hits/misses.
**Monitoring and Runbooks**: Create runbooks for common issues: slow customer search (check Customer service load), payment lookup fails (check Payment service), order create fails (check Orders service latency). Link from dashboard to runbook.
**Gate to Monolith Decommissioning**: Back-office must be fully migrated (no direct SQL reads to monolith) before monolith core decommissioning (Step 18). This step completes organizational cutover.
18. Chaos Engineering, Resilience Testing, and Pre-Peak Validation (depends on: 17)
Validates new distributed architecture survives failure scenarios and peak load without cascading collapse. This step is as much about proving state is coherent as about finding failure modes.
**Chaos Game Days**: Scheduled monthly (or before each peak). Kill each service in turn (Search, Inventory, Orders, Payments, etc.); confirm storefront degrades gracefully (e.g., 'Search temporarily unavailable, catalog browsing still available') rather than failing completely. Kill database replicas; verify service continues with read-only or cached data. Kill message broker; verify no events lost and no reordering. Record each game day; publish findings and mitigation actions.
**Peak-Readiness Gate (Before Each Peak)**: Run six weeks before January and July peaks (mid-November, mid-May):
- **12x Load Test**: Generate realistic 480k orders/day traffic against production-shaped data (8 countries, 3 currencies, 4 languages, realistic product hierarchy). Measure checkout p99 < 5 seconds, search p95 < 1 second, payment < 2 seconds.
- **Capacity Headroom**: Confirm all services autoscale to handle 12x baseline. Database connection pools have headroom. Message broker partitions are sufficient. Cache hit rates do not collapse under load.
- **Rollback Rehearsal**: Execute full rollback of most recent service extraction in load-test environment. Measure rollback time; must be < 30 minutes including data reconciliation.
- **Error Budget Review**: Confirm SLO error budgets not burned significantly. If burned, identify culprit and mitigate before peak.
- **Evidence Publication**: Publish load-test results, capacity headroom metrics, rollback time, and SLO status. Gate is pass/fail; failed gate defers peak exposure and triggers root-cause work.
**Full System Load Test**: All services under load simultaneously. Measure inter-service latencies, database load, message broker throughput. Identify bottlenecks: pricing calculations, search queries, payment provider round-trip time, inventory reservations under concurrent access. Tune:
- Database query indexes
- Connection pool sizes
- Caching strategies
- Message broker partitions
- Service autoscaling thresholds
**Failure Mode Analysis**: Identify top 10 single-point-of-failure risks:
1. Payment provider outage → graceful degradation (pre-authorize smaller amounts?)
2. Inventory service down → checkout blocked; mitigation: cache inventory in checkout orchestrator
3. Pricing service down → checkout blocked; mitigation: cache last-known prices
4. Orders service down → checkout blocked; mitigation: queue orders in Kafka, replay when service recovers
5. Database down → all services blocked; mitigation: read-only replicas for queries
6. Message broker down → no events published; mitigation: outbox patterns ensure no event loss
7. API gateway down → all traffic blocked; mitigation: active-active gateway setup (two regions or multiple providers)
8. Warehouse sync delayed → inventory stale; mitigation: alert threshold, manual intervention process
9. Customer service down → login blocked; mitigation: cache tokens, allow anonymous checkout
10. Search service down → browsing blocked; mitigation: fallback to category list without search
For each failure, document mitigation (architectural change or operational procedure), test in chaos game day, and update runbooks.
**Synthetic Transaction Monitoring**: Implement real-world checkout, return, and search transactions executing every five minutes. Alert on failure before customers notice. Include multi-country, multi-currency variations.
**Performance Baseline Documentation**: Document baseline latencies (checkout, search, payment) at baseline load (40k orders/day). Load test must show no regression at peak; improvements accepted. Document these baselines in runbooks for operations team reference.
19. Monolith Decommissioning and Steady-State Operations (depends on: 18)
Safely retire monolith code once all services stable and production-proven. This step is final validation that new architecture is coherent; incomplete decommissioning signals hidden coupling.
**Module-by-Module Cleanup**: Delete extracted service code from monolith only after that service has survived one full peak (January or July, whichever comes first) or four clean weeks post-cutover, whichever is longer. Before deletion:
- Audit dead code: which stored procedures, views, tables, methods are no longer called
- Verify service API is the only interface for data owned by extracted module
- Confirm no service calls back into monolith code
- Delete extracted logic and dependencies
**Database Decommissioning**: Dropped tables are archived (not deleted) for 90 days (regulatory retention and emergency queries). After 90 days, drop and archive to long-term storage. Monolith database shrinks as modules extracted. When monolith becomes shell (mostly unused), decide: keep as fallback or shut down entirely.
**Cross-Module Stored Procedures**: All stored procedures touching multiple modules' tables must be eliminated before monolith shutdown. If any remain, move logic into services or refactor. Document any that cannot be moved; escalate as risk.
**Backup and Recovery Procedures**: Shift from single monolith snapshot to per-service snapshots. Each service team owns backup/recovery for their database. Document recovery procedures: which services recover in which order, which can tolerate data loss vs. which require point-in-time recovery. Test recovery monthly.
**Architectural Decision Records**: Publish final ADRs documenting:
- Why services were split at these boundaries
- What problems each split solved
- What trade-offs were made
- What cross-service communication patterns emerged
- What monitoring and alerting proved most useful
**Operational Runbooks**: Finalize runbooks for each team:
- Incident response: common failure modes, resolution steps, escalation paths
- Deployment procedures: how to deploy service, rollback procedure, expected latency
- On-call procedures: alert thresholds, page-worthy events, war room communication
- Database procedures: backup, restore, schema migrations, connection pool tuning
**Service Ownership Model**: Confirm each of five teams owns one or more services end-to-end:
- Codebase and CI/CD pipeline
- Database schema and migrations
- On-call rotation and SLOs
- Production incidents
- Capacity planning and scaling
No shared ownership; clear escalation paths between teams.
**Team Ramp-Down of Migration Work**: Migration enablement squad (formed in Step 1) transitions into steady-state platform team. Reduce migration velocity; redirect capacity to feature work on services.
**Exit Criteria and Project Close**:
- All rungs 1–6 of scope ladder complete (or deliberately stopped at rung boundary)
- Both peak seasons (January and July) survived without migration-caused incidents
- All services deployed independently by month 12
- Monolith reduced to < 5% of original codebase or decommissioned entirely
- All architectural decisions documented and team alignment confirmed
**Celebrate and Document Lessons**: Publish retrospective capturing:
- What went well: which techniques proved most valuable (golden master? chaos testing? soak periods?)
- What was hard: which services took longer, which risks materialized
- What would change next time
- Which rungs of scope ladder were reached and why work stopped where it did
**Deferred Work**: Explicitly list architectural or optimization work deferred to follow-up programs (e.g., Pricing DSL refactoring, read-write split at database level, multi-region deployment).
20. Peak Season Validation and Post-Peak Stabilization (depends on: 18, 19)
Proves new architecture survives peak and validates migration is truly complete. January and July peaks are the final test; this step verifies readiness and documents learnings.
**Pre-Peak Confirmation**: One week before peak start (Dec 25 for January peak, June 25 for July peak), confirm:
- All peak-readiness gate checks passed
- All services healthy and responding normally
- Database connection pools at capacity
- Cache hit rates normal
- Message broker lag within SLOs
- On-call rotations staffed
- War room communication channels open
**Peak Monitoring**: During peak (480k orders/day sustained for 2–3 weeks), maintain heightened monitoring:
- Every service dashboard visible in central war room
- Latency p99, p95, p50 trending in real time
- Error rate per service alarmed
- Database query performance monitored
- Message broker lag tracked
- Payment success rate watched (fraud filters, authorizations)
- Inventory reservation accuracy validated hourly
**Incident Response**: Any incident < 5 min MTTR automatically escalates to war room. Team lead validates:
- Root cause (service slow? database? payment provider?)
- Impact (customer-visible? checkout blocked? data corruption?)
- Mitigation (rollback flag? scale service? throttle traffic?)
- Recovery (how long to resolve?)
**Post-Peak Retrospectives**: Within one week of peak completion, each service team retrospectives on:
- Peak traffic patterns observed vs. load-test simulations
- Any incidents: root cause, time-to-detect, time-to-recover
- Performance variations: which services scaled, which became bottlenecks
- Data accuracy: any reconciliation mismatches discovered during peak
- Lessons for next peak
**Capacity Planning**: After peak, analyze:
- Database query times at peak: any unexpected slowdowns?
- Service autoscaling: did services scale early enough? were there cascading failures?
- Cache effectiveness: hit rates at peak vs. baseline
- Message broker: any message loss or reordering?
- Payment provider latency: did provider response times increase during peak?
**Final Validation**: Confirm scope ladder rung achieved:
- Rung 6 complete: back-office migrated, monolith core reduced, checkout orchestration stable
- Teams deployed independently during peak (or blocked from deploying due to freeze, which is correct)
- Zero unplanned downtime caused by migration
- All rollback procedures worked in chaos testing; never needed in production
**Program Closure**: Publish final evidence:
- Peak season metrics (order volume, success rate, latency, errors)
- Service-by-service stability (uptime, incidents, MTTR)
- Scope ladder rung reached
- Explicit deferred work list
- Team feedback and lessons learned
**Next Program Planning**: If rung 7+ desired (e.g., Pricing rules DSL refactoring, multi-region deployment), plan as separate 6-month program. Document in writing; do not creep scope into current program.
--- PROPOSAL 2 ---
Proposal ID: 2a819ee6-3a8b-48c8-a67f-7bcb82c07659
Content:
Estimated Complexity: high
Success Metrics: - Independent deployability: at least 4 of the 5 teams release their own artefact without coordinating with another team by month 5, and all 5 by month 9.
- The 30-minute maintenance window is retired by month 6; no release after that date requires a planned outage.
- Deployment lead time from merge to production is 30 minutes or less for a service, and each team releases at least 3 times per week by month 6.
- Zero unplanned downtime attributable to the migration across the 12 months; availability of 99.95% or better inside each peak window.
- Both January and July peaks pass with no migration-caused incident: 12x baseline load sustained, checkout p99 under 5 seconds, error rate under 0.5%, no queue backlog beyond 5 minutes.
- 100% of migration increments that reach production have a rollback demonstrated in a game day and executable in under 30 minutes.
- The rollback controller reverts a canary automatically on error-rate or latency divergence, proven in at least two live rehearsals per open window.
- Hourly reconciliation shows under 0.001% discrepancy on row counts and checksums per module; zero unexplained business-invariant violations; a monetary mismatch triggers automatic rollback.
- Cross-module joins and cross-module writes originating in application code are zero for every module at the moment it is extracted, enforced by database roles and CI rather than by review.
- Stored procedures touching more than one module's tables: zero for every extracted module.
- Pricing parity: 100% agreement with the golden master on a corpus of at least 1,000,000 historical requests across all 8 countries, 3 currencies and 4 languages, both before and after cutover.
- Search freshness improves from a nightly rebuild to under 30 seconds between a product change and its visibility in search results.
- Warehouse inventory freshness improves from 15 minutes to under 2 minutes end to end.
- Customer auth: zero forced logouts during cutover for both storefront and mobile clients, and no version of the mobile app in the field breaks at any point in the program.
- The checkout transaction remains inside the monolith through both peaks; the saga deferral is documented, accepted and signed off before month 12.
- The peak-readiness gate is passed with published evidence six weeks before both peaks, covering 100% of its defined checks.
- Scope ladder rungs 1–8 are complete within 12 months, or the program stops at a rung boundary in a documented, coherent, peak-safe state.
Steps (18):
1. Calendar-first charter, scope ladder and peak-readiness protocol
The binding constraint in this objective is the commercial calendar, not the technology, so the calendar is decided before anything else. Everything later obeys it.
- Declare the hard freezes against the real sales calendar, in the shape 1 December – 15 January and 1 June – 15 July. Inside a freeze only rollback-enabling and hardening changes ship.
- Reserve four 'risky cut' slots per year, roughly March–April and September–October. February, May, August and November are soak and hardening months and carry no new cutover.
- Forbid any cutover step from starting within six weeks of a freeze. Every cutover must end in a freeze-ready state: both paths live, flags reversible, reconciliation green.
- Publish the scope ladder. Rungs 1–8 are the core objective; rungs 9+ are optional. Slippage stops at a rung boundary in a coherent, peak-safe state, never mid-increment.
- Write the rollback charter: expand/contract schema change, feature-flag kill switch and a game-day rehearsal recorded before go-live.
- Write the abort criteria: the conditions under which the program stops, and who signs off.
- Create a migration enablement squad of six engineers on rotation from the five teams. It owns the platform, the shared cuts and the risky shared data work.
- Budget 40–50% of the five teams' capacity for migration and staff the ladder to that budget rather than filling the year.
2. Executable architecture map, table ownership and boundary enforcement (depends on: 1)
Five teams committing to one repository will silently re-couple anything that is separated and not policed, so enforcement is part of the map, not a later step.
- Run distributed tracing on the monolith for four weeks before drawing any boundary. Real call paths beat static imports for finding true coupling.
- Build a table-to-module and query-to-module map by parsing every SQL statement, ORM mapping and stored procedure, cross-checked against the database's own query logs.
- Assign each of the 350 tables to exactly one owning module. Tables nobody can own are declared contested and scheduled into S7.
- Score each candidate service on coupling, transactional risk, change frequency and peak-path criticality. This ranking drives the extraction order, not intuition.
- Add ArchUnit rules that fail the build on new cross-module Java dependencies, and a SQL linter that fails on cross-module joins and writes. Existing violations are frozen into a baseline file that may only shrink.
- Publish the target service list, the owning team per service and the reasoning as ADRs.
- Re-rank the scope ladder at the month-six review using what the map actually showed.
3. Delivery platform: per-module pipelines, gateway, feature flags, environments (depends on: 1, 2)
No module is extracted until its team can deploy, flag and route on its own.
- Kubernetes namespaces, quotas and autoscaling policies sized for 12x peaks.
- API gateway in front of the monolith from day one as the strangler entry point. Storefront, mobile and back-office traffic all flow through it even while it routes everything to the monolith.
- One CI/CD pipeline and one environment per module. The monolith keeps its pipeline for hotfixes until S5 replaces it.
- A feature-flag service, with every new call path flag-guarded. Flags are the primary rollback instrument for the whole program.
- Golden-path templates for a new service: build, pipeline, observability, health checks, flag integration, database migration tool.
- Two permanent environments: a production-shaped soak environment and a load-test environment able to generate 12x traffic.
- Secrets management and per-environment configuration so behaviour changes never require a monolith redeploy.
4. Observability, business SLOs and the automated rollback controller (depends on: 3)
A canary is only trustworthy if it is judged automatically, so the rollback promise is built once here and reused by every later step.
- Centralised logging, metrics and distributed tracing, with trace correlation across gateway, monolith and every service.
- Instrument the monolith's blind spots: query latency by module, connection-pool saturation, Lucene rebuild duration, warehouse file-exchange lag.
- Define SLOs on business outcomes: checkout success rate, order confirmation p99, search latency, payment authorisation rate, price computation latency, warehouse sync freshness.
- Attach an error budget to each SLO. When a service burns budget, its rollout stops and its flags revert automatically. No negotiation during a peak.
- Build the rollback controller: on error-rate or latency divergence during a canary, the gateway shifts traffic back and disables flags without human action.
- Per-service dashboards a tired engineer can read at 03:00, plus one program dashboard showing progress against the scope ladder.
5. Split the deployment unit and retire the 30-minute maintenance window (depends on: 2, 3)
This is the cheapest large win in the program and it delivers the headline objective — independent deployability — before any process separation, by splitting the build and the release train while the code still runs together.
- Split the single artefact into one build per owning module with a shared parent.
- Allow modules to be released as separate artefacts on the existing runtime first. Independent deployability is a build and release property long before it is a topology property.
- Retire the two-week coordinated release train. Each team gets its own pipeline, cadence and on-call rota, with the gateway and schema compatibility as the contract between teams.
- Adopt expand/contract database migrations so schema and code changes no longer have to ship together.
- Replace the maintenance window with blue-green deployment on two identical stacks, traffic switched at the gateway and rollback performed by switching back.
- Publish the measurement: deployment lead time, deployment frequency per team, and the share of releases that needed no coordination with another team.
6. Seam-level verification: golden master, contracts, shadow diffing and reconciliation (depends on: 2, 3)
A two-million-line monolith cannot reach blanket coverage in a year. Verification is aimed exactly where the cut will be made, which is where it is affordable and where it actually pays.
- Build a characterization harness that records real production requests and responses, anonymised, as a golden master. This is the safety net for every extraction.
- Require every extracted service to pass the golden master on its public API before it takes live traffic, producing a diff report rather than a pass/fail.
- Consumer-driven contract tests between the monolith and each new service, and between services, so a breaking change breaks a build rather than production.
- Shadow traffic mirroring live requests to the new service with field-by-field comparison. The traffic ramp is gated on the divergence rate.
- Per-module data reconciliation as a first-class test: row counts, checksums and business invariants on a schedule, with an owner and an alert threshold.
- Synthetic canary transactions that run a real checkout, return and search every few minutes and alert on functional regression before customers notice.
- Track line coverage only for newly written service code, where the target is 80%. Blanket coverage of the monolith is explicitly not a goal.
7. Data platform: schema ownership, join elimination, CDC, outbox and the four-stage cutover playbook (depends on: 2, 3, 6)
The hardest part of the program, and the part that does not depend on service extraction, so it starts in month one and runs in parallel with everything else.
- Enforce ownership inside the database: one PostgreSQL role per module, able to write only its own schema and read others only through defined views. Cross-schema writes are rejected by the database, not by convention.
- Inventory every stored procedure, attribute it to one module, and either move it into that module's code or leave it as a module-private function. After a module is extracted, no stored procedure may touch two modules' tables.
- Eliminate cross-module joins one at a time, replacing each with an API call, an event-fed read model or a duplicated read-only projection. Track the count per module and drive it to zero before that module is cut.
- Stand up change data capture with Debezium reading the PostgreSQL WAL into Kafka. This publishes monolith domain events with no application change, the lowest-risk start available.
- Add a transactional outbox for new services so their events and their state changes commit together.
- Adopt one reusable four-stage cutover playbook and apply it identically every time. Stage A: the service owns its schema logically, reads from CDC into its own store and serves shadow traffic only. Stage B: reads cut over, the monolith stays system of record. Stage C: writes cut over and the monolith's tables become read-only replicas fed by reverse CDC. Stage D: old tables and dead code are dropped only after a full peak or four clean weeks, whichever is longer.
- Make stage C genuinely reversible: because the sync direction can be flipped, rolling back a write cutover is a configuration change plus a reconciliation pass, not a data restore.
- Build the reconciliation service once, here, so every later cutover has an objective consistency check with thresholds and owners.
- Deliberately defer the 1.2 TB physical split. Services start on the existing cluster in their own schemas; physical separation is post-program work.
8. Rung 1 — Extract Catalogue and Search (depends on: 5, 6, 7)
The first extraction: read-heavy, mostly isolated, no transactional risk. It also pays for itself, because replacing the nightly Lucene rebuild with real-time indexing is a visible business win that buys political cover for the harder cuts.
- Create a Catalog service owning product, category and media tables plus its own search index.
- Feed it from CDC so product and price changes appear in search within seconds instead of after a nightly rebuild.
- Route through the gateway behind a flag and ramp 1% → 5% → 25% → 50% → 100%, with the rollback controller able to revert to the monolith's internal Lucene path at any point.
- Run shadow traffic and compare result sets before any live traffic, then keep the old index warm for two weeks after full cutover.
- Include the mobile app in the same ramp, since it hits the same endpoints.
- Land this cut in a risky-cut slot and let it soak at least four weeks before the freeze.
9. Rung 2 — Extract Returns, the first write path (depends on: 5, 6, 7)
Second extraction and the first that owns writes and a database. Returns is chosen because it is off the peak-critical path, has modest coupling, and exercises the full four-stage playbook at low stakes.
- Build the Returns service with its own schema, consuming order and customer events rather than joining their tables.
- Run the playbook end to end: shadow reads, read cutover, then write cutover with reverse CDC keeping the monolith's tables current.
- Prove the rollback path in a game day before write cutover, including a reconciliation pass and a re-run of the golden master.
- Keep the back-office returns screens on the monolith for now, so staff workflow is untouched by this step.
- Record every friction point and correct the playbook. The real output of this step is a proven, reusable procedure, not just one service.
10. Rung 3 — Extract Inventory and retire the 15-minute warehouse file exchange (depends on: 5, 6, 7)
Removes one of the sharpest coupling points in the system and unblocks the checkout work. Inventory couples the monolith to an external warehouse process rather than to other modules, so it can run in parallel with the other early cuts.
- Build the Inventory service to ingest the warehouse feed directly and publish stock-level events.
- Preserve the existing file-based interface for the first weeks, running the new ingest in parallel with the legacy feed and reconciling hourly until they agree.
- Keep the monolith's inventory tables as an event-fed projection, so cart and checkout keep working unchanged during the cut.
- Design reservation semantics now — reserve, confirm, release, with expiry — even though checkout is not yet extracted. The API is needed later and is cheap to get right here.
- Load-test inventory ingest at 12x, because the warehouse feed schedule and the sales peaks do not always coincide.
- Cut over reads first, then writes, with the rollback controller able to restore the file feed as the source of truth.
11. Rung 4 — Extract Customer Accounts and Loyalty with a conservative auth strategy (depends on: 5, 6, 7, 9)
Customer accounts and loyalty, including the authentication decision. Auth is the step that most often derails e-commerce migrations, so the auth path is deliberately moved last and guarded hardest.
- Build the Customer service owning profile, address and loyalty tables, with country-specific loyalty rules expressed as data where possible and as code where not.
- Keep authentication in the monolith for the first phase. Move token issuance only once customer data is stable, and never within four weeks of a freeze.
- Introduce distributed session handling and a token-validation API so services can verify identity without querying the monolith database.
- Cut over reads, then writes, with reverse CDC, validating against the golden master across all 8 countries and 4 languages.
- Verify the mobile app's session behaviour explicitly, since it holds long-lived sessions the storefront does not.
- Move loyalty point accrual and redemption last, because a loyalty error is a customer-visible financial error, not a technical incident.
12. Rung 5 — Extract Cart (depends on: 8, 10, 11)
The cart is stateful and sits directly in front of checkout. It is done before pricing because the checkout path needs a stable cart boundary to call.
- Build the Cart service on Redis for session and line-item state, validating products and inventory through service calls rather than database joins.
- Make every cart operation idempotent, because a retried add or remove during a peak must not duplicate a line item.
- Keep the cart tables in the monolith as a read-only projection fed by events, for rollback and for the not-yet-migrated back-office screens.
- Ramp traffic while monitoring cart abandonment rate as the business metric, since cart latency shows up as lost revenue rather than as errors.
- Exercise anonymous and authenticated carts separately; they follow different paths and fail in different ways.
- Land this cut in a risky-cut slot with a full four-week soak before the freeze.
13. Rung 6 — Extract Pricing and Promotions as an unchanged black box (depends on: 5, 6, 7)
Extracts the 200,000-line pricing module without rewriting it. The rules are not understood by anyone, so they are wrapped and characterized rather than reverse-engineered. Rule decomposition, documentation and a DSL are explicitly out of scope for these twelve months.
- Build a golden master corpus from at least a million real historical pricing requests and their recorded outputs, covering all 8 countries, 3 currencies, 4 languages, plus every promotion type that can be discovered.
- Invert the module's dependencies rather than its logic: pricing obtains customer, product and inventory data from event-fed read models it owns, not from synchronous fan-out to three services. A fan-out on the price path is the wrong shape at 12x peak.
- Move the pricing code into its own service unchanged, owning its tables after cutover, and expose a single decision API.
- Run it in shadow mode for at least four weeks against live traffic, comparing every computed price with the monolith. Any divergence blocks the ramp.
- Cut over behind a flag with per-country ramps, since a pricing error is a financial and legal exposure in each jurisdiction rather than a technical incident.
- Keep the in-monolith evaluator available and warm as the rollback path for at least one full peak after cutover.
- State in writing that rule decomposition is deferred to a follow-up program, so it does not creep back into this one.
14. Rung 7 — Extract Payment under a stricter regime than anything else (depends on: 5, 6, 7)
Payment mistakes are irreversible and regulatory, so this module gets the strictest controls in the program.
- Build the Payment service owning the integration with the three providers: tokenisation, authorisation, capture, refund and provider webhooks.
- Reduce PCI scope rather than expand it. No raw card data at rest in the new service, credentials in secrets management, no card data in logs or traces.
- Make every payment operation idempotent with explicit idempotency keys, because retries at peak are normal and double charges are not recoverable.
- Cut over provider by provider rather than all three at once, starting with the lowest-volume provider.
- Run the golden master across all decline, timeout, partial-authorisation and refund scenarios, and rehearse the fallback to the monolith's direct provider integration.
- Verify fraud detection and 3-D Secure paths explicitly, since they are usually the least covered and the most visible when they break.
- Land this cut early in a risky-cut slot so it soaks well before the freeze.
15. Rung 8 — Extract Order Management with an explicit state machine (depends on: 9, 10, 13, 14)
Order management becomes the record of truth for the order lifecycle, after the services it depends on exist and are stable.
- Build the Order service with its own database and an explicit order state machine that validates every transition.
- Introduce event sourcing for order status so the audit trail satisfies regulators and fulfilment teams, and so state can be rebuilt after an incident.
- Consume events from payment, inventory and returns rather than polling or joining.
- Cut over reads first for the five teams that query orders, then writes, keeping the monolith's order tables as a reverse-CDC projection.
- Reconcile order counts and monetary totals hourly against the monolith throughout the transition. A monetary mismatch is an immediate rollback, not a ticket.
- Load-test concurrent order state transitions at peak, since the state machine becomes the new serialisation point.
16. Keep the checkout transaction in the monolith for the first peak, and decide on the saga afterwards (depends on: 12, 13, 14, 15)
This is the deliberate difference from the obvious plan. Checkout is the single highest-risk cut and it sits directly on the peak-critical path. A distributed saga across pricing, inventory, payment and orders buys elegance at the cost of the two things the brief protects most: January and July sales.
- Thin the monolith's checkout into a synchronous orchestrator that calls the Pricing, Inventory, Payment and Order services through the gateway.
- Implement compensation inline in the orchestrator — a failed authorisation releases the reservation, a failed order creation voids the authorisation — without introducing a general saga framework.
- Propagate idempotency keys end to end so a retried checkout cannot double-charge or double-reserve.
- Handle the peak case explicitly: when inventory or pricing is slow, checkout must fail to a retryable state, never to a half-committed order.
- Require the peak-readiness gate before the cut that makes checkout depend on remote calls. A failed gate is a stop, not a delay; the monolith stays authoritative.
- Review after a full peak whether the orchestrator is worth extracting as a saga-based Checkout service. That decision belongs to the follow-up program, with peak data in hand.
- Document and sign off the deferral, so it is an accepted design choice rather than an unfinished step.
17. Migrate the back-office, storefront and mobile clients off the monolith database (depends on: 16)
Until the clients move, the monolith's database stays a dependency even where the logic has already left.
- Refactor back-office screens to consume service APIs through the gateway, replacing direct SQL access table by table, starting with orders and customers.
- Add aggregation endpoints where a screen needs several services, plus a short-lived cache so 300 staff do not multiply load on the new services.
- Update the server-rendered storefront to call service APIs while keeping the existing rendering path working behind a flag, so a rendering regression is a flag flip rather than a rollback.
- Point the mobile app at the gateway for migrated endpoints and keep the old endpoints alive for un-updated app versions. No version of the app in the field may break at any point in the program.
- Publish API versioning rules and deprecation windows so teams can change their services without coordinating with client releases.
- Load-test the back-office with 300 concurrent staff on top of peak storefront traffic, since the two now share services.
18. Decommission the extracted modules, validate the second peak, write the exit report (depends on: 17)
Removes what is left and proves the new architecture survives a peak. This step is as much about proving the state is coherent as about deleting code.
- Delete dead code and dropped tables module by module, only after a module has run a full peak or four clean weeks, whichever is longer.
- Keep read-only access to the old database for a defined period for historical and regulatory queries, then archive and decommission it.
- Replace the monolith's remaining cross-module reads with service calls or event-fed projections. The monolith should now be a small set of modules plus the checkout orchestrator.
- Re-run the full 12x load test against the new topology across all 8 countries, 3 currencies and 4 languages, and tune autoscaling, connection pools and broker partitions from the results.
- Run chaos game days: kill each service in turn and confirm the storefront degrades gracefully rather than failing completely.
- Confirm and publish the peak-readiness gate evidence before the second peak. A failed gate defers remaining work rather than risking the peak.
- Write the exit report: final service boundaries, data ownership, runbooks, SLO history, the scope-ladder rung actually reached, and the list of work explicitly deferred to a follow-up program.
--- PROPOSAL 3 ---
Proposal ID: 8a14de17-3842-4134-ba82-c6e281ddebf1
Content:
Estimated Complexity: high
Success Metrics: 1. Zero unplanned downtime during the 12-month migration and subsequent peaks.
2. Peak season (Jan/Jul) capacity maintained at 12x baseline with no performance degradation in checkout flows.
3. 100% of Pricing and Promotion transactions match the Golden Master characterization tests post-extraction.
4. Five teams deploying independently at least once per week without coordination conflicts.
5. All monolith-to-service data synchronization latency under 2 seconds (near real-time).
6. Database size reduced by >40% through extraction and cleanup of legacy unused tables.
7. Search index refresh time reduced from 24 hours (nightly) to < 1 minute (real-time).
Steps (16):
1. Program Governance, Peak Calendar, and Scope Ladder
Establish the binding constraints of the program before any technical work begins. The calendar dictates that the January and July sales peaks are immovable objects; therefore, all migration steps must be scheduled around them.
2. Platform Foundation: Kubernetes, Gateway, and Observability (depends on: 1)
Deploy the infrastructure layer required to run services independently and observe traffic flow. This includes a Kubernetes cluster for workloads, an API Gateway as the central routing control point, and a full observability stack (Tracing, Metrics, Logs). The Gateway is the primary mechanism for rollback via traffic shifting.
3. Data Foundation: CDC, Outbox Pattern, and Transactional Events (depends on: 1, 2)
Implement Change Data Capture (Debezium) and a Transactional Outbox pattern in the monolith. This creates the event backbone required for eventual consistency and allows new services to subscribe to monolith changes without touching the legacy code logic. This step runs in parallel with platform setup.
4. Architectural Decoupling: Table Ownership and Anti-Corruption Layer (depends on: 2)
Define strict ownership for the 350 tables and implement an Anti-Corruption Layer (ACL) to intercept cross-module dependencies. This involves creating separate database schemas or logical boundaries for high-coupling areas like Orders and Catalogue to prepare for physical separation.
5. Characterization Test Harness: The Golden Master (depends on: 2, 3)
Build a replay engine and capture a 'Golden Master' corpus of production traffic. This automated test suite records request/response pairs from the monolith, creating a baseline for validation. This is critical for the Pricing module and high-traffic endpoints where refactoring is impossible.
6. First Extraction Pilot: Catalogue and Search (Read-Heavy) (depends on: 3, 4, 5)
Extract the Catalogue and Search services. These are low-risk (read-heavy) and validate the strangler fig pattern. Implement real-time search indexing via CDC events, replacing the nightly Lucene rebuild. Use the Golden Master to verify product data and search results match the monolith.
7. Second Extraction: Inventory Synchronization (depends on: 3, 5)
Extract Inventory management, specifically handling the integration with the external warehouse system (15-minute sync). This removes a critical dependency from the monolith and enables real-time stock visibility. The service acts as the single source of truth for stock levels.
8. Third Extraction: Customer Profile and Identity (depends on: 3, 4)
Extract Customer Accounts and Profile management. Move authentication logic and customer data ownership to a dedicated service. Ensure the Mobile App and Storefront can authenticate against the new service while maintaining session compatibility via JWT or shared session state.
9. Pricing Module Stabilization: Black Box Extraction (depends on: 5)
Extract the 200,000 LOC Pricing and Promotions module as a 'Black Box' service. Do not refactor the logic; wrap it. Use the Golden Master to validate 100% accuracy across all 8 countries and complex promotion rules. This step is strictly scheduled outside of any peak season.
10. Core Transactional Extraction: Orders and Order Management (depends on: 6, 7, 8, 9)
Extract the Order Management domain, including order creation, state machines, and lifecycle tracking. This service acts as the consumer of events from Inventory, Pricing, and Customer services. It replaces the monolith's direct order processing logic.
11. Checkout Orchestration and Saga Implementation (depends on: 7, 9, 10)
Implement the Checkout Service, acting as the orchestrator (Saga) for the payment process. It coordinates the distributed transaction across Cart, Pricing, Inventory, and Payments. It handles compensating transactions (e.g., releasing inventory on payment failure) to ensure data consistency.
12. Payment Provider Integration Service (depends on: 10, 11)
Extract the logic responsible for connecting to the three payment providers. This service handles authorization, capture, and refunds. By isolating this, the monolith no longer holds sensitive payment processing logic, reducing PCI scope and coupling.
13. Return and Refund Workflow Extraction (depends on: 10, 12)
Extract the Returns and Refunds logic. This service consumes order events to trigger return workflows, updates inventory, and requests refunds from the Payment Service. This completes the reverse logistics capability as a microservice.
14. Legacy Monolith Decommissioning: Strangler Finish (depends on: 10, 11, 12, 13)
Remove the extracted logic from the monolith. The monolith is now a legacy shell containing only the storefront rendering layer (which delegates to APIs) and potentially the Back-Office (if not yet migrated). This step involves rigorous cleanup of unused code and database tables.
15. Back-Office Migration and Staff Tooling (depends on: 14)
Migrate the Back-Office (300 staff users) to use the new service APIs. This may involve a dedicated BFF (Backend for Frontend) service that aggregates data from Orders, Customers, and Inventory for the staff UI, replacing direct database joins in the monolith.
16. Operational Handover and Autonomous Team Setup (depends on: 15)
Finalize team ownership. Each of the five teams is assigned to specific services (e.g., Team A owns Inventory and Search, Team B owns Orders and Checkout). Transfer on-call rotations and disaster recovery runbooks to the new services.
Instructions:
1. Carefully evaluate each proposal considering:
- Clarity and detail of the proposed steps.
- Overall alignment with the Main Objective.
- Quality and relevance of the proposed success metrics.
- Coherence of dependencies between steps (if any).
2. Think deeply about each proposal, analyzing its strengths and weaknesses. Consider how well each proposal addresses the main objective and which one would be most effective.
After your thorough analysis, give the Proposal ID of the selected proposal and a one- or two-sentence justification of your choice.
{"selected_proposal_id": "eaa6af3c-28c3-480e-b9b1-be2c22215422", "justification": "Proposal 1 is the most complete and rigorous plan. It explicitly makes the calendar a binding constraint (Step 1), defines hard freeze windows and peak-readiness gates before each risk, structures work into six rungs with deliberate stop points to prevent mid-increment slippage, includes 18+ success metrics covering all aspects (business outcomes, technical precision, rollback verification, team autonomy), details 20 comprehensive steps with explicit dependencies, and includes mandatory game-day rehearsals and chaos testing for every extraction. Most critically for the stated objective, it fully addresses how to preserve peak-season capacity by building peak-readiness gates six weeks before peaks, defining clear rollback procedures for every step, and ensuring soak periods of at least four weeks before freezes. Proposals 2 and 3 both have merit, but Proposal 2 defers checkout saga extraction beyond the 12-month window, and Proposal 3 conspicuously omits explicit freeze windows and peak-readiness gates despite the brief stating the calendar is a 'binding constraint'—a disqualifying gap for a migration where January and July sales 'must not be put at risk.'"} |
| deepseek-flash_voter_2 | deepseek-flash · deepseek/deepseek-flash |
Proposal A · claudeHaiku4.5_refine_1 winner | Proposal 1 is the most complete and internally coherent: its 20 dependency-linked steps cover platform, data (CDC/outbox/four-stage cutover), seam-level verification, rollback automation, chaos testing and explicit peak-readiness gates, and its success metrics are the most precise and measurable (pricing parity on 1M+ requests, reconciliation thresholds, rollback <30 min, 12x peak SLAs). It also matches the brief's core constraints—calendar-first scheduling, no feature freeze, reversible every step, and protected January/July peaks—without the thinner coverage seen in Proposal 3. Proposal 2 is a strong contender with a sensible deferral of the checkout saga, but Proposal 1's greater depth and explicit rollback/reconciliation machinery make it the safer, more complete plan. |
18.5k in · 1.1k out · 7 s | show[SYSTEM]
You are an expert and objective evaluator of project plan proposals.
Your task is to select the BEST proposal based on criteria of completeness, clarity, and alignment with the main objective.
Use your internal reasoning processes to thoroughly analyze each proposal, considering all aspects and implications.
Take as much time and space as you need to evaluate each proposal in depth before making your decision.
Every text field you write will be read by a busy person, so write for them: short sentences, one idea each, in short paragraphs. Text fields accept Markdown: separate paragraphs with a blank line, use a bullet list when you enumerate things and plain paragraphs when you explain or argue, and bold at most one key phrase per paragraph. A text of more than three sentences must be split into paragraphs; never deliver a single unbroken block of text.
[HUMAN]
Main Objective: "A mid-size European fashion retailer runs its e-commerce on a 10-year-old monolith: Java 8 / Spring, about 2 million lines, one PostgreSQL database of 1.2 TB with 350 tables and heavy use of stored procedures and cross-module joins. It serves 8 countries, 3 currencies and 4 languages, with about 40,000 orders a day and peaks of 12x during sales. The monolith contains: the storefront (server-rendered, plus a separate mobile app hitting the same endpoints), catalogue and search (a Lucene index rebuilt nightly), pricing and promotions (the most complex module, 200,000 lines, with country-specific rules nobody fully understands), cart and checkout with three payment providers, order management, inventory synchronised every 15 minutes with the warehouse system via file exchange, customer accounts and loyalty, returns, and a back-office used by 300 staff. Deployments happen every two weeks as a single artefact with a 30-minute maintenance window; test coverage is 25% and mostly unit tests. Five teams of 8 developers, each organised around a business area but all committing to the same repository.
Plan the migration to independently deployable services over 12 months with no feature freeze, no unplanned downtime and the ability to roll back every step, preserving the peak-season capacity (sales in January and July must not be put at risk)."
Proposals to Evaluate:
--- PROPOSAL 1 ---
Proposal ID: eaa6af3c-28c3-480e-b9b1-be2c22215422
Content:
Estimated Complexity: high
Success Metrics:
- **Zero unplanned downtime**: 100% availability throughout 12-month migration (excluding planned 30-min blue-green deployments); no production incidents attributable to migration architecture
- **Peak seasons protected**: January and July peaks (480k orders/day) sustain zero degradation caused by migration; checkout p99 ≤ 5 seconds, payment authorization ≤ 2 seconds, error rate ≤ 0.5%, no queue backlog > 5 minutes
- **Independent deployability**: All eight services independently deployable by month 12; each team releases on own cadence (weekly or faster) with zero cross-team deployment coordination; 100% of service releases verified rollback-capable in < 30 minutes
- **Rollback-proven**: Every production increment has rehearsed, documented, tested rollback path (expand/contract migrations, feature flags, reverse CDC); monthly chaos game days validate rollback procedures; zero increments reach production without passing rollback gate
- **Data consistency**: Hourly reconciliation shows < 0.001% row-count and checksum discrepancy between service databases and monolith (pre-decommissioning); zero business-invariant violations (no duplicate orders, no lost payments, no inventory oversells)
- **Pricing correctness**: 100% agreement between new Pricing service and golden-master corpus across 1M+ historical requests covering all 8 countries, 3 currencies, 4 languages, all promotion types; zero pricing errors post-cutover
- **Search freshness**: Product availability reflects in search within < 60 seconds of inventory change (vs. nightly rebuild); search latency p95 unchanged or improved at peak load
- **Warehouse sync improvement**: Inventory synchronization lag reduced from 15 minutes to < 2 minutes end-to-end; 100% of daily warehouse updates processed; no missed sync cycles during migration
- **Payment processing**: Zero regressions with all three payment providers; fraud detection active and effective; PCI-DSS compliance maintained; idempotency prevents duplicate charges; payment success rate ≥ 99.5% at peak
- **Back-office operations unaffected**: All 300 staff seamlessly using service APIs; service aggregation endpoints maintain p95 latency ≤ 500 ms; bulk operations (refunds, order status updates) complete within SLA
- **Test coverage for services**: All newly written service code reaches 80%+ line coverage; golden master validates 100% of public API contracts before production traffic; contract tests (Pact) prevent breaking changes between services
- **Peak-readiness gate passed**: Six weeks before each peak (mid-November, mid-May), gate published showing 12x load test results, capacity headroom, rollback rehearsal duration, and SLO status; failed gate defers work; evidence published publicly
- **Team independence by month 12**: Five teams deployed independently; each owns service codebase, pipeline, database schema, on-call rotation, SLOs; no cross-team pull requests blocking releases; internal developer platform (golden-path templates, self-service deployments) adopted by all teams
- **Scope ladder completed**: Rungs 1–6 reached by month 12 (or deliberately stopped at rung boundary with documented justification); all services proven at peak; monolith reduced to < 5% or decommissioned
- **Calendar adherence**: No major extractions or refactors during freeze windows (Dec 1–Jan 15, June 1–July 15); all production increments land in open windows with minimum 4-week soak before freeze; timeline published and adhered to
- **Event-driven architecture validated**: Kafka message broker handles 480k+ messages/day at peak; no message loss, no ordering violations; outbox pattern ensures every domain event persists atomically
- **Fallback capacity maintained**: Monolith rollback path kept warm and functional (receiving live traffic or ready-to-receive via feature flag) until each service survives one full peak; no service extracted without proven rollback capability
Steps (20):
1. Program Setup, Scope Ladder, Organizational Model, and Peak-Safe Calendar
Establishes the governance framework and constraints that all later work obeys. The calendar is the binding constraint—January and July peaks must not be put at risk—so it is decided first, before any technical choices.
**Inception and Baselines**: Run a two-week inception to establish current state: build time, deployment lead time, change failure rate, MTTR per team, module-change frequency, database load profiles (all measurable, not asserted).
**Calendar and Freeze Windows**: Declare hard freezes from December 1–January 15 and June 1–July 15; only rollback-enabling and hardening changes allowed during freezes. Confirm two open delivery windows per year (February–May and August–November); all migration work must fit these windows. No change on checkout path lands within four weeks of a freeze.
**Scope Ladder**: Define ranked rungs 1–6 that deliver the core objective; rungs 7+ are optional. Slippage means stopping at a rung boundary, never mid-increment. Rungs: 1. Platform ready. 2. Search extracted and proven. 3. Returns and Inventory proven at low stakes. 4. Payment and Orders stable. 5. Checkout orchestration live and soaking. 6. Back-office migrated, monolith core reduced.
**Organizational Model**: Define service-aligned teams (Search, Orders, Inventory, Payments, Customer, Fulfillment) with clear ownership, on-call rotations, and SLOs per service. Each team owns codebase, pipeline, database schema, and incidents by month 6. Transition plan: teams split duties (monolith maintenance + service) until month 3, then shift to service-primary by month 6.
**Rollback Charter**: Every increment ships an expand/contract database change, a feature-flag kill switch, and a recorded game-day rehearsal. No go-live without tested rollback in < 30 minutes.
**Peak-Readiness Gate**: Define gate to run six weeks before each peak (mid-November, mid-May): 12x load test, capacity headroom check, rollback rehearsal, error-budget review. Gate is pass/fail; failed gate defers work to next window.
**Capacity Budget**: Allocate 40–50% of five teams' capacity for migration; staff scope ladder to fit capacity, not to fill the year. Create migration enablement squad of six rotating engineers to own platform, shared cuts, and risky data work.
2. Executable Architecture Map, Table Ownership, and Boundary Enforcement (depends on: 1)
Produces an architecture map that the build itself enforces. Five teams in one repo will silently re-couple anything separated if not policed, so enforcement is embedded in the map.
**Real Coupling via Tracing**: Instrument monolith with distributed tracing; let it run four weeks to capture real call paths—static imports miss true coupling.
**Table Ownership Matrix**: Parse every SQL statement, ORM mapping, and stored procedure; cross-check against database query logs. Build table-to-module and query-to-module map. Assign every 350 table to exactly one owning module; tables nobody can own are 'contested' and scheduled into data work (Step 7).
**Scoring and Extraction Sequence**: Score each candidate service on coupling, transactional risk, change frequency, and peak-path criticality. This ranking (not intuition) drives extraction order.
**Enforcement via Automation**: Add ArchUnit rules to CI to fail builds on new cross-module Java dependencies (existing violations frozen in baseline that may only shrink). Add SQL linter to CI to fail on cross-module joins and cross-module writes (same shrinking baseline). Violations tracked weekly in architecture review.
**Stored Procedure Audit**: Inventory all stored procedures; attribute to owning module; plan move into module code or leave as module-private function. No stored procedure may touch two modules' tables post-extraction.
**Architecture Decision Records**: Publish target service list, owning team per service, and reasoning as ADRs.
**Mid-Program Review**: Hold review at month 6 to re-rank scope ladder using what the map actually revealed. This is the one planned re-planning point of the program.
3. Delivery Platform: Per-Service Pipelines, Gateway, Feature Flags, and Environments (depends on: 1, 2)
Builds the delivery and traffic machinery that makes every later step reversible. No service is extracted until its team can deploy, flag, and route independently.
**Kubernetes and Namespaces**: Extend platform on Kubernetes (or existing container platform) with one namespace per service, quotas, and autoscaling sized for 12x peak (480k orders/day). Establish dev/staging/prod with strict resource isolation.
**API Gateway**: Deploy API gateway (Kong, AWS ALB) in front of monolith as strangler entry point. Storefront, mobile app, and back-office traffic flow through gateway from day one, even while routing everything to monolith. Gateway enforces rate limiting, bulkheads, timeouts, and circuit breakers.
**Feature-Flag Service**: Deploy centralized feature-flag system (LaunchDarkly, Unleash). Require every new call path to be flag-guarded. Flags are the primary rollback instrument; changes to traffic routing require no code deployment.
**Per-Module CI/CD Pipeline**: Give every module its own independent CI/CD pipeline and environment. Monolith keeps current pipeline for hotfixes until Step 5 replaces it. Pipeline includes automated security scanning, performance baselines, and contract-test gates.
**Secrets and Configuration**: Introduce secrets management (Vault) and per-environment configuration. Behavioral changes require no monolith redeploy.
**Golden-Path Templates**: Define reusable templates for new services: build layout, Dockerfile, pipeline stages, observability instrumentation, health checks, feature-flag integration, database migration tool. Extraction starts from template, not blank page.
**Permanent Environments**: Reserve two full-size environments: (1) production-like soak environment for multi-week stability validation, (2) load-test environment capable of 12x traffic generation against production-shaped data (8 countries, 3 currencies, 4 languages, realistic product catalog).
4. Observability, Business SLOs, Error Budgets, and Automated Rollback Controller (depends on: 3)
Makes the system observable so canaries are judged automatically and reverted without human guessing. This is the prerequisite for rollback promises in all later steps.
**Observability Foundation**: Deploy centralized logging (ELK/Loki), metrics (Prometheus/Grafana), and distributed tracing (Jaeger) with trace correlation working across gateway, monolith, and every new service from day one.
**Blind-Spot Instrumentation**: Instrument monolith's unmeasured aspects: query latency by module, connection-pool saturation, Lucene rebuild duration, warehouse file-exchange lag, stored procedure execution time, lock contention.
**Business SLOs**: Define SLOs on business outcomes, not infrastructure:
- Checkout success rate ≥ 99.5%
- Order confirmation latency p99 ≤ 5 seconds at baseline (40k orders/day) and peak (480k orders/day)
- Search result latency p95 ≤ 1 second
- Payment authorization latency ≤ 2 seconds
- Price computation latency ≤ 200 ms
- Warehouse sync freshness ≤ 2 minutes end-to-end (vs. current 15 minutes)
- Cross-module data consistency: hourly reconciliation shows < 0.001% row-count discrepancy
**Error Budget and Rollback Policy**: Attach error budget to each SLO. When a service burns budget (or latency diverges > threshold during canary), its rollout stops automatically and flags revert without negotiation. Document policy explicitly; use during peaks without exception.
**Automated Rollback Controller**: Build system that monitors error rate and latency divergence during canary. On breach, gateway shifts traffic back and flags disable automatically. Fallback requires no human intervention. Test this automation in monthly game days.
**Dashboards**: Create per-service dashboards readable by tired engineers at 3 AM (traffic, errors, latency p50/p95/p99, database load). Create program dashboard showing progress against scope ladder, rung by rung.
5. Pricing Module: Rules Catalog and Golden-Master Characterization (Parallel with Data Platform) (depends on: 1, 2)
Catalog the 200k LOC pricing engine behavior before any extraction attempt. This is the foundational risk mitigation for the most complex module; it runs in parallel with data platform work (Step 7) because it is independent of infrastructure.
**Rules Discovery and Documentation**: Analyze and document all pricing rules in scope: country-specific logic (8 countries), currency handling (3 currencies), promotional rules, seasonal pricing, bulk discounts, loyalty point applications, regional variations. Create a living rules inventory.
**Historical Request Corpus**: Capture at least 1 million real historical pricing requests from production logs, covering all 8 countries, 3 currencies, 4 languages, all promotion types discoverable, edge cases, peak-season variations. Record exact inputs and outputs.
**Golden-Master Characterization Suite**: Build automated harness to replay corpus against monolith, capturing deterministic responses. This suite is the 'golden master': any new pricing service must match 100% of outputs. Suite becomes the automated gate for pricing extraction (Step 14).
**Test Data Expansion**: Supplement historical data with synthetic edge cases: multi-currency conversions, minimum purchase thresholds, conflicting promotions, time-based seasonal rules, inventory-driven pricing, customer-segment overrides.
**Dependency Mapping**: Explicitly document which customer attributes, product attributes, inventory levels, time-based factors, and external parameters affect pricing. Identify all cross-module dependencies that pricing currently reads from monolith (e.g., customer loyalty status from Customer module, product hierarchy from Catalogue module).
**Baseline Validation**: Run golden master against monolith to establish baseline passing rate. Document any non-deterministic behavior or race conditions found. This baseline is locked; no drift allowed during migration.
**CI Gate Definition**: Define hard rule: pricing service extraction cannot proceed until characterization tests pass 100% against both monolith and new service. Any divergence blocks ramp. This gate is not negotiable.
6. Seam-Level Verification: Golden Master, Contracts, Shadow Diffing, and Reconciliation (depends on: 2, 3)
Replaces impossible goal of blanket test coverage with verification exactly at the cut point. A 2M-line monolith cannot reach 70% coverage in a year; a service boundary can be verified to very high standard in weeks.
**Characterization Harness for All Services**: Build framework to record real production requests (anonymizing PII) and replay against monolith. Capture full responses as golden master. Every extracted service must pass golden master on its public API before taking live traffic. Output a diff report, not pass/fail.
**Consumer-Driven Contracts (Pact)**: Require contracts between monolith and each new service, and between services themselves. A change on one side breaks a build instead of waiting for production. Contracts versioned; breaking changes trigger explicit communication plan.
**Shadow Traffic and Response Diffing**: Mirror live requests to new service; compare responses field by field (not just status codes). Measure divergence rate continuously. Gate traffic ramp on divergence < 0.01% for 48 hours.
**Per-Module Data Reconciliation**: Build data reconciliation as first-class test, not afterthought. Compare row counts, checksums, and business invariants on hourly schedule. Owner assigned; alert threshold set. Reconciliation runs continuously during transition period (Stages A–C of cutover playbook).
**Synthetic Canary Transactions**: Implement real checkout, return, and search transactions executing every few minutes. Alert on functional regression before customers notice. Include multi-country, multi-currency variations.
**Explicit Non-Goal**: Do not pursue blanket line coverage of monolith. Track coverage only for newly written service code, target 80%. Seam-level verification replaces this impossible goal.
7. Data Platform: Schema Ownership, Join Elimination, CDC, Transactional Outbox, and Four-Stage Cutover Playbook (depends on: 2, 3)
The hardest and most under-specified part of most migrations. This work is independent of service extraction, so it starts in month 1 and runs in parallel. It is the foundation for reversible data transitions.
**Database-Enforced Ownership**: Assign every PostgreSQL table to exactly one module. Create one role per module, able to write only its own schema and to read others only through defined views. Database rejects cross-schema writes at the engine level, not by convention. Test this enforcement in CI.
**Stored Procedure Refactoring**: Inventory every stored procedure, attribute it to owning module. Either move logic into that module's application code or leave as module-private database function. After extraction, no stored procedure may touch two modules' tables.
**Cross-Module Join Elimination**: Eliminate cross-module joins one at a time, replacing each with an API call (preferred during cutover), an event-fed materialized read model, or a duplicated read-only projection. Track count per module; drive to zero before that module is extracted.
**Change Data Capture (CDC)**: Deploy Debezium reading PostgreSQL WAL into Kafka. This publishes monolith domain events with zero application change—lowest-risk start possible. Configure per-table CDC; test at peak load (480k events/day during 12x peak).
**Transactional Outbox Pattern**: For all new services, add outbox table. When service writes business state, it writes domain event atomically in same transaction. Outbox relay publishes to Kafka, ensuring no event loss. Implement poison-pill handling for failed publishes.
**Four-Stage Cutover Playbook (Reusable)**: Define one playbook applied identically every service extraction:
- **Stage A** (Shadow-Read): Service owns schema logically, reads from CDC into its own store, serves shadow traffic only. Monolith remains system of record; no cutover yet.
- **Stage B** (Read Cutover): Reads cut over to new service via flag. Monolith stays system of record via reverse-CDC replication. Rollback is flag flip + reconciliation pass.
- **Stage C** (Write Cutover): Writes cut over to new service. Monolith tables become read-only replicas fed by reverse CDC from service. Rollback is configuration change (flip sync direction) + reconciliation, not data restore.
- **Stage D** (Deletion): Old tables and dead code dropped only after module has survived one full peak (January or July) or four clean weeks, whichever is longer. Maintain 90-day read-only archive of old tables for regulatory retention and emergency queries.
**Reconciliation Service**: Build now (not later) so every cutover has objective consistency check. Compare row counts, business-invariant checksums, monetary totals hourly. Owner assigned; thresholds set. Mismatch is immediate rollback signal.
**Storage Migration Timeline**: New services start on existing cluster with own schemas. Physical database split (move to separate cluster) happens only once module is stable and proven at peak. This removes a critical-path blocker and allows parallelization.
8. Extract Catalogue and Search: Read-Heavy Pilot Service (depends on: 5, 6, 7)
First extraction, chosen because it is read-heavy, isolated, and carries no transactional risk. It also pays for itself: replacing nightly Lucene rebuild with real-time indexing is a visible business win that buys political cover for harder cuts.
**New Catalogue Service**: Create service owning product, category, media, and attributes tables. Build search API using Elasticsearch/OpenSearch with real-time indexing.
**CDC Feed**: Subscribe to CDC stream from monolith. ProductUpdated, PriceChanged, InventoryUpdated events trigger real-time search index refresh. Product availability reflects in search within < 60 seconds of change (vs. nightly rebuild).
**Shadow Traffic and Diff Validation**: Route requests through gateway behind feature flag. Run shadow mode: send requests to both monolith Lucene and new Search service; compare result sets field by field. Measure divergence; require < 0.01% for 48 hours before traffic ramp.
**Gradual Traffic Ramp**: 1% → 5% → 25% → 50% → 100% using feature flags and canary deployments. Rollback controller monitors latency and error rates; reverts flag if breach. Keep old Lucene index warm for two weeks post-cutover as rollback target.
**Mobile App Verification**: Verify mobile app behavior explicitly; it hits same endpoints. Test session persistence, offline search cache behavior, and app version compatibility during ramp.
**Four-Stage Playbook**: Execute Stages A–D as defined in Step 7. Stage A (shadow) lasts 1 week minimum. Stage B (read cutover) lasts 2 weeks. Stage C does not apply (reads only). Stage D (cleanup) after one peak or four weeks.
**Soak Period**: Land this extraction in open delivery window; soak at least four weeks before freeze (Dec 1 or June 1). No extraction reaches production less than four weeks before a freeze.
9. Extract Returns: Low-Stakes Proof of Four-Stage Playbook (depends on: 5, 6, 7)
Second extraction and first write-path proof. Returns is chosen because it is off peak-critical path, has modest coupling, and exercises full four-stage playbook at low risk. Primary output is a proven, reusable procedure, not just one service.
**Returns Service**: Build with own schema. Consume order and customer events rather than joining their tables. Implement return state machine: Requested → Approved → Shipped → Received → Refunded.
**Full Four-Stage Execution**: Apply Stages A–D end-to-end with explicit recorded game day validating each stage rollback path. Stage A (shadow reads) for 1 week. Stage B (read cutover) for 2 weeks. Stage C (write cutover) with reverse CDC. Stage D (cleanup) after one peak or four weeks.
**Rollback Rehearsal**: Before write cutover, execute full game day: simulate service failure mid-cutover, trigger rollback (reverse CDC, flag flip, reconciliation), verify all data consistent, re-run golden master, confirm back-office queries still work. Record this session; play back monthly.
**Back-Office Screens**: Keep back-office returns screens on monolith for now (staff workflow untouched). Returns service is API-only; back-office integration comes later (Step 18).
**Friction Point Capture**: Record every operational friction, process gap, and test hole discovered during extraction. Update playbook from learnings. This step is as much about process validation as about extracting Returns.
**Soak and Timing**: Execute in open window; soak returns service for minimum four weeks before any freeze. Gate to proceeding to Inventory (Step 10) is successful four-week soak with zero rollbacks and full reconciliation agreement.
10. Extract Inventory: Warehouse Sync Improvement and Reservation Semantics (depends on: 5, 6, 7)
Removes one of sharpest coupling points (15-minute file-exchange lag) and unblocks checkout work. Inventory runs in parallel with returns because it couples monolith to external warehouse system, not to other modules.
**Inventory Service**: Ingest warehouse feed directly (SFTP/API) instead of monolith polling. Design reservation semantics now: Reserve (place hold), Confirm (finalize after order), Release (cancel reservation on timeout/failure), with explicit timeout windows. Own stock levels and reservations per product per location.
**Parallel Feeds During Transition**: Run new ingest in parallel with legacy 15-minute feed. Reconcile hourly until both agree. This validates the new ingest does not miss updates or duplicate changes.
**Monolith Inventory Tables as Projection**: Keep monolith's inventory tables as read-only replicas fed by CDC from new service during Stage C (write cutover). Cart and checkout continue calling monolith queries unchanged during cutover; no checkout changes yet.
**Four-Stage Execution**: Apply Stages A–D. Stage A (shadow ingests and reads) for 2 weeks (must survive two 15-minute sync windows and validate no drift). Stage B (read cutover) for 2 weeks. Stage C (write cutover) with reverse CDC. Stage D (cleanup) after one peak.
**Peak-Load Testing**: Load-test inventory ingest at 12x (400k SKU updates/day during peak). Warehouse feed schedule and sales peaks do not always align; test worst-case concurrency. Validate no reservation deadlocks, no stock over-sells.
**Cutover Order**: Inventory read cutover must complete before Cart extraction (Step 13) to avoid monolith checkout calling new Inventory service via internal API during transition.
**Soak and Gate**: Soak minimum four weeks before freeze. Gate to proceeding to Customer (Step 11) is four-week soak with zero reconciliation mismatches and warehouse feed lag improved to < 2 minutes.
11. Extract Customer Accounts and Loyalty: Conservative Authentication Strategy (depends on: 9, 10)
Extracts customer identity, profile, and loyalty programs. Authentication is deliberately placed late and guarded hardest because auth failures derail e-commerce migrations most often.
**Customer Service**: Own profile, address, and loyalty tables. Implement country-specific loyalty rules (8 countries, different point accrual rates) as data-driven rules where possible, code where not. Design API: GetCustomer, UpdateProfile, GetLoyaltyBalance, RedeemPoints, AccruePoints.
**Authentication Strategy Phase 1**: Keep authentication (login) in monolith for now. Customer service exposes only data APIs; token issuance remains monolith's responsibility. This delays risky auth cutover; less risk to peak season.
**Distributed Session Handling**: Introduce Redis-backed distributed sessions. Services can verify customer identity without querying monolith database. Implement token-validation API so services can verify bearer tokens without round-tripping to monolith.
**Data Cutover**: Execute four-stage playbook. Stage A (shadow reads) for 1 week. Stage B (read cutover) for 2 weeks. Stage C (write cutover) for new customers, address updates, loyalty accrual. Stage D (cleanup) after one peak.
**Golden Master for All Countries**: Golden master captures customer queries across all 8 countries, all 4 languages, and all loyalty-rule variations. Shadow-traffic diff must show < 0.01% divergence before read cutover.
**Mobile App Session Behavior**: Test mobile app's long-lived sessions explicitly; storefront does not hold sessions same way. Validate token refresh, session timeout, and app version compatibility during cutover.
**Loyalty Accrual Last**: Move loyalty point accrual and redemption last within this step (Stage C final substep). Loyalty error is customer-visible financial error, not technical incident; guard hardest.
**Soak and Gate**: Soak minimum four weeks. Gate to proceeding to Cart (Step 13) is successful loyalty accrual cutover with zero customer complaints and full reconciliation agreement.
12. Extract Cart: Stateful Session Service (depends on: 6, 7, 10, 11)
Extract shopping cart, which is stateful and sits directly in front of checkout. Extracted before Pricing and Checkout because both depend on stable Cart boundary.
**Cart Service on Redis**: Build on Redis (or PostgreSQL with session affinity) for session and line-item state. Validate products and inventory through service API calls rather than direct database joins. Design API: AddItem, RemoveItem, UpdateQuantity, GetCart, ApplyCoupon, ClearCart.
**Idempotent Operations**: Every cart operation is idempotent. Retried add during peak does not duplicate line item. Retried remove is safe. Implement via unique constraint on (session, sku) or idempotency-key header.
**Monolith Cart Tables as Projection**: Keep monolith's cart tables as read-only projections fed by CDC from Cart service. Back-office screens continue reading old cart tables for abandoned-cart analytics (not yet migrated to service APIs in this step).
**Four-Stage Execution**: Apply Stages A–D. Stage A (shadow reads) for 1 week. Stage B (read cutover) for 2 weeks (use feature flag; gradual ramp 10% → 50% → 100%). Stage C (write cutover to service); Stage D after one peak.
**Business Metric Monitoring**: Cart latency surfaces as lost revenue (abandonment), not just error logs. Track cart abandonment rate and add-to-cart latency as primary success metrics during ramp.
**Anonymous vs. Authenticated Carts**: Test both paths separately; they follow different session-tracking mechanisms and fail in different ways. Ensure cart persists across login boundary.
**Soak Before Freeze**: Land in open window; soak minimum four weeks before freeze (Dec 1 or June 1). Gate to proceeding to Pricing (Step 14) is four-week soak with cart abandonment rate unchanged or improved and zero lost transactions.
13. Extract Pricing as Black Box Using Golden-Master Validation (depends on: 5, 6, 7)
Extract 200k LOC pricing logic as-is without rewriting. Rules are not understood by anyone, so wrap and characterize rather than refactor. Rule decomposition deferred to follow-up program in writing.
**Wrap Without Refactor**: Move pricing code into dedicated service, unchanged. Service owns pricing tables post-cutover. Expose single decision API: ComputePrice(customerId, productId, locationId, timestamp, quantityId, loyaltyStatus) → {price, applicablePromotions, taxes, currency}.
**Dependency Injection for Reads**: Refactor pricing's dependencies so it obtains customer data via Customer service API, product data via Catalogue service API, inventory via Inventory service API. No direct cross-module database joins.
**Golden-Master Validation**: Run characterization test suite (built in Step 5) against new service. Require 100% output match on all 1M historical requests across all 8 countries, 3 currencies, 4 languages, all promotion types, edge cases. Any divergence blocks ramp; no exceptions.
**Shadow Mode Duration**: Run shadow traffic against live pricing requests for minimum four weeks, comparing every computed price with monolith. Measure divergence continuously. Divergence > 0.001% blocks ramp.
**Gradual Cutover by Country**: Cut over per-country rather than all-at-once. Start with lowest-revenue country, validate four weeks per country, then ramp to others. Per-country flags allow independent rollback.
**Rollback Path**: Keep monolith's pricing evaluator available and warm as rollback target for at least one full peak (January or July) after cutover. Maintain ability to flip back to monolith pricing via feature flag without data restore.
**Four-Stage Playbook**: Stages A–D applied to pricing tables. Stage A (shadow) 4+ weeks. Stage B (read cutover) 2 weeks per country. Stage C (write cutover) per country. Stage D (cleanup) after one full peak.
**Deferred Refactoring in Writing**: Publish decision that pricing rule decomposition, DSL, and optimization are explicitly deferred to follow-up program after this migration stabilizes. Include this in all project communications and retrospectives.
14. Extract Payment: PCI-Strict Regime and Provider-by-Provider Cutover (depends on: 5, 6, 7)
Extract payment processing with stricter regime than any other service. Mistakes are irreversible and regulatory. Extracted before checkout orchestration because checkout cannot be decomposed without payment boundary.
**Payment Service**: Own integration with three payment providers (tokenization, authorization, capture, refund, provider webhooks). Design API: AuthorizePayment(idempotencyKey, amount, currency, cardToken, customerId) → {authorizationId, status}; CapturePayment(authorizationId); RefundPayment(captureId); HandleWebhook(webhookPayload).
**PCI Scope Reduction**: No raw card data at rest in service. Card data flows directly from client to provider (tokenization); only tokens stored in Payment service. Credentials in secrets management (Vault). No card data in logs or distributed traces.
**Idempotent Operations**: Explicit idempotency-key handling. Every payment request is idempotent; retries at peak are normal and must not double-charge. Implement via idempotency-key deduplication store (Redis with TTL).
**Provider-by-Provider Cutover**: Cut over one provider at a time (start with lowest-volume provider). Stage A (shadow) 2 weeks per provider. Stage B (read cutover, not applicable). Stage C (write cutover) for each provider, maintain fallback to monolith for other providers. Test each provider's decline, timeout, 3-D Secure, and chargeback scenarios explicitly.
**Golden Master Scenarios**: Golden master covers all three providers, all decline reasons, timeouts, partial authorizations, refund scenarios, chargebacks. Shadow traffic compares full payment outcomes (authId, status, amount, timestamp) before any live provider cutover.
**Fraud Detection and 3-D Secure**: These paths are usually least-tested and most visible when broken. Test explicitly; goldne master includes fraud-decline and 3-D Secure flows. Verify fraud rules and thresholds carry over unchanged.
**Fallback Orchestration**: Monolith retains ability to handle payment directly (as fallback) until second peak after Payment service cutover. Checkout can gracefully degrade to old payment path via feature flag if new service fails.
**Four-Stage Playbook**: Stages A–D per provider. Stage C (write) is highest-risk; ensure golden master passes 100% and shadow mode shows zero divergence before each provider cutover. Gate and soak strictly: four weeks minimum before any freeze.
**Soak and Timing**: Land in open window (Feb–May or Aug–Nov). Complete all three providers' Stage C cutover by month 9 to allow checkout orchestration time to soak before freeze.
15. Extract Orders: Event-Sourced Record of Truth (depends on: 9, 13, 14)
Extract order management as authoritative record of order lifecycle. Extracted after Inventory, Pricing, and Payment exist and are stable, because Orders depends on all three.
**Orders Service**: Own order tables and order state machine. Implement explicit state transitions: Pending → Confirmed → Preparing → Shipped → Delivered, with validation blocking invalid transitions. Design API: CreateOrder(cartId, customerId, paymentAuthorizationId), GetOrder(orderId), CancelOrder(orderId), UpdateOrderStatus.
**Event Sourcing**: Record all order state changes as immutable events. Build order state from event log on demand. Audit trail satisfies regulators and fulfillment teams; state can be rebuilt after incidents. Include: OrderCreated, PaymentAuthorized, InventoryReserved, OrderConfirmed, OrderPreparing, OrderShipped, OrderDelivered, OrderCancelled.
**Event Consumption**: Consume events from Payment service (PaymentAuthorized, PaymentFailed), Inventory service (StockReserved, ReservationCancelled), and Returns service (ReturnInitiated, RefundIssued) rather than polling or joining.
**Four-Stage Playbook**: Stages A–D. Stage A (shadow) for 1 week. Stage B (read cutover) for 2 weeks, with gradual flag ramp. Five teams that query orders start reading from Orders service via API. Stage C (write cutover): new orders written to Orders service; monolith order tables become reverse-CDC read-only replicas. Stage D after one peak.
**Reconciliation: Monetary and Row-Count**: Reconcile order counts and monetary totals hourly against monolith throughout transition. Currency totals must match exactly (cent-by-cent); row count discrepancies are immediate rollback. Implement automated reconciliation query; owner assigned; threshold zero.
**Concurrent Order Transitions**: Load-test concurrent order state transitions at 480k/day peak. Order state machine becomes serialization point for distributed system; ensure no race conditions, no duplicate orders, no lost transactions.
**Soak Before Checkout**: Complete Orders cutover (Stages A–C) by month 9. Soak minimum four weeks before freeze. Gate to proceeding to Checkout (Step 16) is four-week soak with zero monetary reconciliation mismatches and zero order duplicates.
16. Extract Checkout: Distributed Saga Orchestration (Highest Risk) (depends on: 12, 13, 14, 15)
Highest-risk extraction, deliberately placed last among transactional work and only after components it orchestrates are individually proven at scale. This step composes independent services into coherent checkout flow.
**Checkout Orchestrator Service**: Build service that coordinates checkout: cart validation, price computation, inventory reservation, payment authorization, order creation. Design as explicit saga with named steps and compensating actions.
**Saga Orchestration**: Implement synchronous saga (single coordinator) or asynchronous (choreography via events), chosen based on latency testing (target checkout p99 < 5 seconds at peak). Synchronous preferred for checkout because customer waits; failure is visible. Steps:
1. Validate cart via Cart service
2. Compute price via Pricing service (cached if < 1 second old)
3. Reserve inventory via Inventory service
4. Authorize payment via Payment service
5. Create order via Orders service
**Compensating Transactions**: For every step, define compensation:
- Step 3 fails: Release inventory reservation
- Step 4 fails: Release inventory reservation, void authorization (if possible)
- Step 5 fails: Release reservation, void authorization, return payment to customer
- Step 2 recomputes and differs: Increase price, reject order; or decrease price, accept at old price (business rules decision, document explicitly)
**Idempotency End-to-End**: Checkout request includes idempotency key (unique per browser session + timestamp). Service deduplicates on this key. Retried checkout cannot double-charge or double-reserve; returns previous result.
**Timeout Handling**: Inventory reservation expires in 15 minutes (configurable). Payment authorization valid for 7 days (provider-specific). Order creation never times out; if hanging, manually investigate. Saga must fail safe to retryable state, never to half-committed order.
**Shadow Traffic Before Live**: Mirror live checkout traffic (100% of checkout requests during business hours) to new orchestration for minimum 2 weeks before any live cutover. Compare full outcomes: order ID, order total, inventory reservations, payment authorization IDs, error messages. Divergence > 0.001% blocks live cutover.
**Live Ramp During Open Window**: Ramp live traffic only during open delivery window (Feb–May or Aug–Nov). Gate and soak strictly: minimum four weeks before freeze. Keep monolith checkout path fully functional and warm (receiving live traffic via feature flag) as rollback target until Checkout service has survived one full peak.
**Peak-Readiness Gate Mandatory**: Hold six-week peak-readiness gate (Step 19) before proceeding to back-office migration (Step 18). Failed gate stops this work immediately and defers to next window.
17. Migrate Back-Office, Storefront, and Mobile Clients to Service APIs (depends on: 16)
Moves 300 back-office staff and client applications off monolith database direct access. Until this step, monolith database remains live dependency even where logic moved.
**Back-Office Screen Refactoring**: Migrate screens table by table. Replace direct SQL with service API calls through gateway. Start with orders (call Orders service), then customers (call Customer service), then inventory (call Inventory service). Build aggregation endpoints: /orders/{id}/full-details calls Orders + Payments + Inventory + Returns services, caches 30 seconds, returns unified response.
**Aggregation Endpoints and Caching**: Services are now call-chain away, not co-located. Back-office latency would suffer without caching. Implement short-lived cache (TTL 30 seconds) for frequently accessed data (customer profiles, recent orders). Graceful degradation: if one service slow, show cached data and alert staff.
**Storefront and Mobile App**: Both hit same endpoints (via gateway). Update storefront (server-rendered) to call service APIs while keeping old path functional behind feature flag; rendering regression becomes flag flip, not rollback. Mobile app points at gateway for migrated endpoints; keep old endpoints alive for un-updated app versions (users do not upgrade on schedule). Implement API versioning: v1 (legacy monolith), v2 (service APIs); clients request version in Accept header.
**API Versioning and Deprecation Windows**: Publish versioning rules: breaking changes trigger major version bump (v2 → v3). Old version supported for minimum 90 days after major release. Client teams must upgrade within window; do not force upgrade. Document deprecation timeline in API spec.
**Load Test Back-Office Concurrency**: Test 300 concurrent staff on top of peak storefront (480k orders/day). New services now carry both loads; autoscaling and database connection pools must handle burst. Simulate realistic staff queries: order searches, customer history, bulk refunds.
**Distributed Tracing for Debugging**: Every back-office request traced across services. Staff can view trace in UI; operations team can see which service was slow. Trace includes: request start, service calls, database queries, cache hits/misses.
**Monitoring and Runbooks**: Create runbooks for common issues: slow customer search (check Customer service load), payment lookup fails (check Payment service), order create fails (check Orders service latency). Link from dashboard to runbook.
**Gate to Monolith Decommissioning**: Back-office must be fully migrated (no direct SQL reads to monolith) before monolith core decommissioning (Step 18). This step completes organizational cutover.
18. Chaos Engineering, Resilience Testing, and Pre-Peak Validation (depends on: 17)
Validates new distributed architecture survives failure scenarios and peak load without cascading collapse. This step is as much about proving state is coherent as about finding failure modes.
**Chaos Game Days**: Scheduled monthly (or before each peak). Kill each service in turn (Search, Inventory, Orders, Payments, etc.); confirm storefront degrades gracefully (e.g., 'Search temporarily unavailable, catalog browsing still available') rather than failing completely. Kill database replicas; verify service continues with read-only or cached data. Kill message broker; verify no events lost and no reordering. Record each game day; publish findings and mitigation actions.
**Peak-Readiness Gate (Before Each Peak)**: Run six weeks before January and July peaks (mid-November, mid-May):
- **12x Load Test**: Generate realistic 480k orders/day traffic against production-shaped data (8 countries, 3 currencies, 4 languages, realistic product hierarchy). Measure checkout p99 < 5 seconds, search p95 < 1 second, payment < 2 seconds.
- **Capacity Headroom**: Confirm all services autoscale to handle 12x baseline. Database connection pools have headroom. Message broker partitions are sufficient. Cache hit rates do not collapse under load.
- **Rollback Rehearsal**: Execute full rollback of most recent service extraction in load-test environment. Measure rollback time; must be < 30 minutes including data reconciliation.
- **Error Budget Review**: Confirm SLO error budgets not burned significantly. If burned, identify culprit and mitigate before peak.
- **Evidence Publication**: Publish load-test results, capacity headroom metrics, rollback time, and SLO status. Gate is pass/fail; failed gate defers peak exposure and triggers root-cause work.
**Full System Load Test**: All services under load simultaneously. Measure inter-service latencies, database load, message broker throughput. Identify bottlenecks: pricing calculations, search queries, payment provider round-trip time, inventory reservations under concurrent access. Tune:
- Database query indexes
- Connection pool sizes
- Caching strategies
- Message broker partitions
- Service autoscaling thresholds
**Failure Mode Analysis**: Identify top 10 single-point-of-failure risks:
1. Payment provider outage → graceful degradation (pre-authorize smaller amounts?)
2. Inventory service down → checkout blocked; mitigation: cache inventory in checkout orchestrator
3. Pricing service down → checkout blocked; mitigation: cache last-known prices
4. Orders service down → checkout blocked; mitigation: queue orders in Kafka, replay when service recovers
5. Database down → all services blocked; mitigation: read-only replicas for queries
6. Message broker down → no events published; mitigation: outbox patterns ensure no event loss
7. API gateway down → all traffic blocked; mitigation: active-active gateway setup (two regions or multiple providers)
8. Warehouse sync delayed → inventory stale; mitigation: alert threshold, manual intervention process
9. Customer service down → login blocked; mitigation: cache tokens, allow anonymous checkout
10. Search service down → browsing blocked; mitigation: fallback to category list without search
For each failure, document mitigation (architectural change or operational procedure), test in chaos game day, and update runbooks.
**Synthetic Transaction Monitoring**: Implement real-world checkout, return, and search transactions executing every five minutes. Alert on failure before customers notice. Include multi-country, multi-currency variations.
**Performance Baseline Documentation**: Document baseline latencies (checkout, search, payment) at baseline load (40k orders/day). Load test must show no regression at peak; improvements accepted. Document these baselines in runbooks for operations team reference.
19. Monolith Decommissioning and Steady-State Operations (depends on: 18)
Safely retire monolith code once all services stable and production-proven. This step is final validation that new architecture is coherent; incomplete decommissioning signals hidden coupling.
**Module-by-Module Cleanup**: Delete extracted service code from monolith only after that service has survived one full peak (January or July, whichever comes first) or four clean weeks post-cutover, whichever is longer. Before deletion:
- Audit dead code: which stored procedures, views, tables, methods are no longer called
- Verify service API is the only interface for data owned by extracted module
- Confirm no service calls back into monolith code
- Delete extracted logic and dependencies
**Database Decommissioning**: Dropped tables are archived (not deleted) for 90 days (regulatory retention and emergency queries). After 90 days, drop and archive to long-term storage. Monolith database shrinks as modules extracted. When monolith becomes shell (mostly unused), decide: keep as fallback or shut down entirely.
**Cross-Module Stored Procedures**: All stored procedures touching multiple modules' tables must be eliminated before monolith shutdown. If any remain, move logic into services or refactor. Document any that cannot be moved; escalate as risk.
**Backup and Recovery Procedures**: Shift from single monolith snapshot to per-service snapshots. Each service team owns backup/recovery for their database. Document recovery procedures: which services recover in which order, which can tolerate data loss vs. which require point-in-time recovery. Test recovery monthly.
**Architectural Decision Records**: Publish final ADRs documenting:
- Why services were split at these boundaries
- What problems each split solved
- What trade-offs were made
- What cross-service communication patterns emerged
- What monitoring and alerting proved most useful
**Operational Runbooks**: Finalize runbooks for each team:
- Incident response: common failure modes, resolution steps, escalation paths
- Deployment procedures: how to deploy service, rollback procedure, expected latency
- On-call procedures: alert thresholds, page-worthy events, war room communication
- Database procedures: backup, restore, schema migrations, connection pool tuning
**Service Ownership Model**: Confirm each of five teams owns one or more services end-to-end:
- Codebase and CI/CD pipeline
- Database schema and migrations
- On-call rotation and SLOs
- Production incidents
- Capacity planning and scaling
No shared ownership; clear escalation paths between teams.
**Team Ramp-Down of Migration Work**: Migration enablement squad (formed in Step 1) transitions into steady-state platform team. Reduce migration velocity; redirect capacity to feature work on services.
**Exit Criteria and Project Close**:
- All rungs 1–6 of scope ladder complete (or deliberately stopped at rung boundary)
- Both peak seasons (January and July) survived without migration-caused incidents
- All services deployed independently by month 12
- Monolith reduced to < 5% of original codebase or decommissioned entirely
- All architectural decisions documented and team alignment confirmed
**Celebrate and Document Lessons**: Publish retrospective capturing:
- What went well: which techniques proved most valuable (golden master? chaos testing? soak periods?)
- What was hard: which services took longer, which risks materialized
- What would change next time
- Which rungs of scope ladder were reached and why work stopped where it did
**Deferred Work**: Explicitly list architectural or optimization work deferred to follow-up programs (e.g., Pricing DSL refactoring, read-write split at database level, multi-region deployment).
20. Peak Season Validation and Post-Peak Stabilization (depends on: 18, 19)
Proves new architecture survives peak and validates migration is truly complete. January and July peaks are the final test; this step verifies readiness and documents learnings.
**Pre-Peak Confirmation**: One week before peak start (Dec 25 for January peak, June 25 for July peak), confirm:
- All peak-readiness gate checks passed
- All services healthy and responding normally
- Database connection pools at capacity
- Cache hit rates normal
- Message broker lag within SLOs
- On-call rotations staffed
- War room communication channels open
**Peak Monitoring**: During peak (480k orders/day sustained for 2–3 weeks), maintain heightened monitoring:
- Every service dashboard visible in central war room
- Latency p99, p95, p50 trending in real time
- Error rate per service alarmed
- Database query performance monitored
- Message broker lag tracked
- Payment success rate watched (fraud filters, authorizations)
- Inventory reservation accuracy validated hourly
**Incident Response**: Any incident < 5 min MTTR automatically escalates to war room. Team lead validates:
- Root cause (service slow? database? payment provider?)
- Impact (customer-visible? checkout blocked? data corruption?)
- Mitigation (rollback flag? scale service? throttle traffic?)
- Recovery (how long to resolve?)
**Post-Peak Retrospectives**: Within one week of peak completion, each service team retrospectives on:
- Peak traffic patterns observed vs. load-test simulations
- Any incidents: root cause, time-to-detect, time-to-recover
- Performance variations: which services scaled, which became bottlenecks
- Data accuracy: any reconciliation mismatches discovered during peak
- Lessons for next peak
**Capacity Planning**: After peak, analyze:
- Database query times at peak: any unexpected slowdowns?
- Service autoscaling: did services scale early enough? were there cascading failures?
- Cache effectiveness: hit rates at peak vs. baseline
- Message broker: any message loss or reordering?
- Payment provider latency: did provider response times increase during peak?
**Final Validation**: Confirm scope ladder rung achieved:
- Rung 6 complete: back-office migrated, monolith core reduced, checkout orchestration stable
- Teams deployed independently during peak (or blocked from deploying due to freeze, which is correct)
- Zero unplanned downtime caused by migration
- All rollback procedures worked in chaos testing; never needed in production
**Program Closure**: Publish final evidence:
- Peak season metrics (order volume, success rate, latency, errors)
- Service-by-service stability (uptime, incidents, MTTR)
- Scope ladder rung reached
- Explicit deferred work list
- Team feedback and lessons learned
**Next Program Planning**: If rung 7+ desired (e.g., Pricing rules DSL refactoring, multi-region deployment), plan as separate 6-month program. Document in writing; do not creep scope into current program.
--- PROPOSAL 2 ---
Proposal ID: 2a819ee6-3a8b-48c8-a67f-7bcb82c07659
Content:
Estimated Complexity: high
Success Metrics: - Independent deployability: at least 4 of the 5 teams release their own artefact without coordinating with another team by month 5, and all 5 by month 9.
- The 30-minute maintenance window is retired by month 6; no release after that date requires a planned outage.
- Deployment lead time from merge to production is 30 minutes or less for a service, and each team releases at least 3 times per week by month 6.
- Zero unplanned downtime attributable to the migration across the 12 months; availability of 99.95% or better inside each peak window.
- Both January and July peaks pass with no migration-caused incident: 12x baseline load sustained, checkout p99 under 5 seconds, error rate under 0.5%, no queue backlog beyond 5 minutes.
- 100% of migration increments that reach production have a rollback demonstrated in a game day and executable in under 30 minutes.
- The rollback controller reverts a canary automatically on error-rate or latency divergence, proven in at least two live rehearsals per open window.
- Hourly reconciliation shows under 0.001% discrepancy on row counts and checksums per module; zero unexplained business-invariant violations; a monetary mismatch triggers automatic rollback.
- Cross-module joins and cross-module writes originating in application code are zero for every module at the moment it is extracted, enforced by database roles and CI rather than by review.
- Stored procedures touching more than one module's tables: zero for every extracted module.
- Pricing parity: 100% agreement with the golden master on a corpus of at least 1,000,000 historical requests across all 8 countries, 3 currencies and 4 languages, both before and after cutover.
- Search freshness improves from a nightly rebuild to under 30 seconds between a product change and its visibility in search results.
- Warehouse inventory freshness improves from 15 minutes to under 2 minutes end to end.
- Customer auth: zero forced logouts during cutover for both storefront and mobile clients, and no version of the mobile app in the field breaks at any point in the program.
- The checkout transaction remains inside the monolith through both peaks; the saga deferral is documented, accepted and signed off before month 12.
- The peak-readiness gate is passed with published evidence six weeks before both peaks, covering 100% of its defined checks.
- Scope ladder rungs 1–8 are complete within 12 months, or the program stops at a rung boundary in a documented, coherent, peak-safe state.
Steps (18):
1. Calendar-first charter, scope ladder and peak-readiness protocol
The binding constraint in this objective is the commercial calendar, not the technology, so the calendar is decided before anything else. Everything later obeys it.
- Declare the hard freezes against the real sales calendar, in the shape 1 December – 15 January and 1 June – 15 July. Inside a freeze only rollback-enabling and hardening changes ship.
- Reserve four 'risky cut' slots per year, roughly March–April and September–October. February, May, August and November are soak and hardening months and carry no new cutover.
- Forbid any cutover step from starting within six weeks of a freeze. Every cutover must end in a freeze-ready state: both paths live, flags reversible, reconciliation green.
- Publish the scope ladder. Rungs 1–8 are the core objective; rungs 9+ are optional. Slippage stops at a rung boundary in a coherent, peak-safe state, never mid-increment.
- Write the rollback charter: expand/contract schema change, feature-flag kill switch and a game-day rehearsal recorded before go-live.
- Write the abort criteria: the conditions under which the program stops, and who signs off.
- Create a migration enablement squad of six engineers on rotation from the five teams. It owns the platform, the shared cuts and the risky shared data work.
- Budget 40–50% of the five teams' capacity for migration and staff the ladder to that budget rather than filling the year.
2. Executable architecture map, table ownership and boundary enforcement (depends on: 1)
Five teams committing to one repository will silently re-couple anything that is separated and not policed, so enforcement is part of the map, not a later step.
- Run distributed tracing on the monolith for four weeks before drawing any boundary. Real call paths beat static imports for finding true coupling.
- Build a table-to-module and query-to-module map by parsing every SQL statement, ORM mapping and stored procedure, cross-checked against the database's own query logs.
- Assign each of the 350 tables to exactly one owning module. Tables nobody can own are declared contested and scheduled into S7.
- Score each candidate service on coupling, transactional risk, change frequency and peak-path criticality. This ranking drives the extraction order, not intuition.
- Add ArchUnit rules that fail the build on new cross-module Java dependencies, and a SQL linter that fails on cross-module joins and writes. Existing violations are frozen into a baseline file that may only shrink.
- Publish the target service list, the owning team per service and the reasoning as ADRs.
- Re-rank the scope ladder at the month-six review using what the map actually showed.
3. Delivery platform: per-module pipelines, gateway, feature flags, environments (depends on: 1, 2)
No module is extracted until its team can deploy, flag and route on its own.
- Kubernetes namespaces, quotas and autoscaling policies sized for 12x peaks.
- API gateway in front of the monolith from day one as the strangler entry point. Storefront, mobile and back-office traffic all flow through it even while it routes everything to the monolith.
- One CI/CD pipeline and one environment per module. The monolith keeps its pipeline for hotfixes until S5 replaces it.
- A feature-flag service, with every new call path flag-guarded. Flags are the primary rollback instrument for the whole program.
- Golden-path templates for a new service: build, pipeline, observability, health checks, flag integration, database migration tool.
- Two permanent environments: a production-shaped soak environment and a load-test environment able to generate 12x traffic.
- Secrets management and per-environment configuration so behaviour changes never require a monolith redeploy.
4. Observability, business SLOs and the automated rollback controller (depends on: 3)
A canary is only trustworthy if it is judged automatically, so the rollback promise is built once here and reused by every later step.
- Centralised logging, metrics and distributed tracing, with trace correlation across gateway, monolith and every service.
- Instrument the monolith's blind spots: query latency by module, connection-pool saturation, Lucene rebuild duration, warehouse file-exchange lag.
- Define SLOs on business outcomes: checkout success rate, order confirmation p99, search latency, payment authorisation rate, price computation latency, warehouse sync freshness.
- Attach an error budget to each SLO. When a service burns budget, its rollout stops and its flags revert automatically. No negotiation during a peak.
- Build the rollback controller: on error-rate or latency divergence during a canary, the gateway shifts traffic back and disables flags without human action.
- Per-service dashboards a tired engineer can read at 03:00, plus one program dashboard showing progress against the scope ladder.
5. Split the deployment unit and retire the 30-minute maintenance window (depends on: 2, 3)
This is the cheapest large win in the program and it delivers the headline objective — independent deployability — before any process separation, by splitting the build and the release train while the code still runs together.
- Split the single artefact into one build per owning module with a shared parent.
- Allow modules to be released as separate artefacts on the existing runtime first. Independent deployability is a build and release property long before it is a topology property.
- Retire the two-week coordinated release train. Each team gets its own pipeline, cadence and on-call rota, with the gateway and schema compatibility as the contract between teams.
- Adopt expand/contract database migrations so schema and code changes no longer have to ship together.
- Replace the maintenance window with blue-green deployment on two identical stacks, traffic switched at the gateway and rollback performed by switching back.
- Publish the measurement: deployment lead time, deployment frequency per team, and the share of releases that needed no coordination with another team.
6. Seam-level verification: golden master, contracts, shadow diffing and reconciliation (depends on: 2, 3)
A two-million-line monolith cannot reach blanket coverage in a year. Verification is aimed exactly where the cut will be made, which is where it is affordable and where it actually pays.
- Build a characterization harness that records real production requests and responses, anonymised, as a golden master. This is the safety net for every extraction.
- Require every extracted service to pass the golden master on its public API before it takes live traffic, producing a diff report rather than a pass/fail.
- Consumer-driven contract tests between the monolith and each new service, and between services, so a breaking change breaks a build rather than production.
- Shadow traffic mirroring live requests to the new service with field-by-field comparison. The traffic ramp is gated on the divergence rate.
- Per-module data reconciliation as a first-class test: row counts, checksums and business invariants on a schedule, with an owner and an alert threshold.
- Synthetic canary transactions that run a real checkout, return and search every few minutes and alert on functional regression before customers notice.
- Track line coverage only for newly written service code, where the target is 80%. Blanket coverage of the monolith is explicitly not a goal.
7. Data platform: schema ownership, join elimination, CDC, outbox and the four-stage cutover playbook (depends on: 2, 3, 6)
The hardest part of the program, and the part that does not depend on service extraction, so it starts in month one and runs in parallel with everything else.
- Enforce ownership inside the database: one PostgreSQL role per module, able to write only its own schema and read others only through defined views. Cross-schema writes are rejected by the database, not by convention.
- Inventory every stored procedure, attribute it to one module, and either move it into that module's code or leave it as a module-private function. After a module is extracted, no stored procedure may touch two modules' tables.
- Eliminate cross-module joins one at a time, replacing each with an API call, an event-fed read model or a duplicated read-only projection. Track the count per module and drive it to zero before that module is cut.
- Stand up change data capture with Debezium reading the PostgreSQL WAL into Kafka. This publishes monolith domain events with no application change, the lowest-risk start available.
- Add a transactional outbox for new services so their events and their state changes commit together.
- Adopt one reusable four-stage cutover playbook and apply it identically every time. Stage A: the service owns its schema logically, reads from CDC into its own store and serves shadow traffic only. Stage B: reads cut over, the monolith stays system of record. Stage C: writes cut over and the monolith's tables become read-only replicas fed by reverse CDC. Stage D: old tables and dead code are dropped only after a full peak or four clean weeks, whichever is longer.
- Make stage C genuinely reversible: because the sync direction can be flipped, rolling back a write cutover is a configuration change plus a reconciliation pass, not a data restore.
- Build the reconciliation service once, here, so every later cutover has an objective consistency check with thresholds and owners.
- Deliberately defer the 1.2 TB physical split. Services start on the existing cluster in their own schemas; physical separation is post-program work.
8. Rung 1 — Extract Catalogue and Search (depends on: 5, 6, 7)
The first extraction: read-heavy, mostly isolated, no transactional risk. It also pays for itself, because replacing the nightly Lucene rebuild with real-time indexing is a visible business win that buys political cover for the harder cuts.
- Create a Catalog service owning product, category and media tables plus its own search index.
- Feed it from CDC so product and price changes appear in search within seconds instead of after a nightly rebuild.
- Route through the gateway behind a flag and ramp 1% → 5% → 25% → 50% → 100%, with the rollback controller able to revert to the monolith's internal Lucene path at any point.
- Run shadow traffic and compare result sets before any live traffic, then keep the old index warm for two weeks after full cutover.
- Include the mobile app in the same ramp, since it hits the same endpoints.
- Land this cut in a risky-cut slot and let it soak at least four weeks before the freeze.
9. Rung 2 — Extract Returns, the first write path (depends on: 5, 6, 7)
Second extraction and the first that owns writes and a database. Returns is chosen because it is off the peak-critical path, has modest coupling, and exercises the full four-stage playbook at low stakes.
- Build the Returns service with its own schema, consuming order and customer events rather than joining their tables.
- Run the playbook end to end: shadow reads, read cutover, then write cutover with reverse CDC keeping the monolith's tables current.
- Prove the rollback path in a game day before write cutover, including a reconciliation pass and a re-run of the golden master.
- Keep the back-office returns screens on the monolith for now, so staff workflow is untouched by this step.
- Record every friction point and correct the playbook. The real output of this step is a proven, reusable procedure, not just one service.
10. Rung 3 — Extract Inventory and retire the 15-minute warehouse file exchange (depends on: 5, 6, 7)
Removes one of the sharpest coupling points in the system and unblocks the checkout work. Inventory couples the monolith to an external warehouse process rather than to other modules, so it can run in parallel with the other early cuts.
- Build the Inventory service to ingest the warehouse feed directly and publish stock-level events.
- Preserve the existing file-based interface for the first weeks, running the new ingest in parallel with the legacy feed and reconciling hourly until they agree.
- Keep the monolith's inventory tables as an event-fed projection, so cart and checkout keep working unchanged during the cut.
- Design reservation semantics now — reserve, confirm, release, with expiry — even though checkout is not yet extracted. The API is needed later and is cheap to get right here.
- Load-test inventory ingest at 12x, because the warehouse feed schedule and the sales peaks do not always coincide.
- Cut over reads first, then writes, with the rollback controller able to restore the file feed as the source of truth.
11. Rung 4 — Extract Customer Accounts and Loyalty with a conservative auth strategy (depends on: 5, 6, 7, 9)
Customer accounts and loyalty, including the authentication decision. Auth is the step that most often derails e-commerce migrations, so the auth path is deliberately moved last and guarded hardest.
- Build the Customer service owning profile, address and loyalty tables, with country-specific loyalty rules expressed as data where possible and as code where not.
- Keep authentication in the monolith for the first phase. Move token issuance only once customer data is stable, and never within four weeks of a freeze.
- Introduce distributed session handling and a token-validation API so services can verify identity without querying the monolith database.
- Cut over reads, then writes, with reverse CDC, validating against the golden master across all 8 countries and 4 languages.
- Verify the mobile app's session behaviour explicitly, since it holds long-lived sessions the storefront does not.
- Move loyalty point accrual and redemption last, because a loyalty error is a customer-visible financial error, not a technical incident.
12. Rung 5 — Extract Cart (depends on: 8, 10, 11)
The cart is stateful and sits directly in front of checkout. It is done before pricing because the checkout path needs a stable cart boundary to call.
- Build the Cart service on Redis for session and line-item state, validating products and inventory through service calls rather than database joins.
- Make every cart operation idempotent, because a retried add or remove during a peak must not duplicate a line item.
- Keep the cart tables in the monolith as a read-only projection fed by events, for rollback and for the not-yet-migrated back-office screens.
- Ramp traffic while monitoring cart abandonment rate as the business metric, since cart latency shows up as lost revenue rather than as errors.
- Exercise anonymous and authenticated carts separately; they follow different paths and fail in different ways.
- Land this cut in a risky-cut slot with a full four-week soak before the freeze.
13. Rung 6 — Extract Pricing and Promotions as an unchanged black box (depends on: 5, 6, 7)
Extracts the 200,000-line pricing module without rewriting it. The rules are not understood by anyone, so they are wrapped and characterized rather than reverse-engineered. Rule decomposition, documentation and a DSL are explicitly out of scope for these twelve months.
- Build a golden master corpus from at least a million real historical pricing requests and their recorded outputs, covering all 8 countries, 3 currencies, 4 languages, plus every promotion type that can be discovered.
- Invert the module's dependencies rather than its logic: pricing obtains customer, product and inventory data from event-fed read models it owns, not from synchronous fan-out to three services. A fan-out on the price path is the wrong shape at 12x peak.
- Move the pricing code into its own service unchanged, owning its tables after cutover, and expose a single decision API.
- Run it in shadow mode for at least four weeks against live traffic, comparing every computed price with the monolith. Any divergence blocks the ramp.
- Cut over behind a flag with per-country ramps, since a pricing error is a financial and legal exposure in each jurisdiction rather than a technical incident.
- Keep the in-monolith evaluator available and warm as the rollback path for at least one full peak after cutover.
- State in writing that rule decomposition is deferred to a follow-up program, so it does not creep back into this one.
14. Rung 7 — Extract Payment under a stricter regime than anything else (depends on: 5, 6, 7)
Payment mistakes are irreversible and regulatory, so this module gets the strictest controls in the program.
- Build the Payment service owning the integration with the three providers: tokenisation, authorisation, capture, refund and provider webhooks.
- Reduce PCI scope rather than expand it. No raw card data at rest in the new service, credentials in secrets management, no card data in logs or traces.
- Make every payment operation idempotent with explicit idempotency keys, because retries at peak are normal and double charges are not recoverable.
- Cut over provider by provider rather than all three at once, starting with the lowest-volume provider.
- Run the golden master across all decline, timeout, partial-authorisation and refund scenarios, and rehearse the fallback to the monolith's direct provider integration.
- Verify fraud detection and 3-D Secure paths explicitly, since they are usually the least covered and the most visible when they break.
- Land this cut early in a risky-cut slot so it soaks well before the freeze.
15. Rung 8 — Extract Order Management with an explicit state machine (depends on: 9, 10, 13, 14)
Order management becomes the record of truth for the order lifecycle, after the services it depends on exist and are stable.
- Build the Order service with its own database and an explicit order state machine that validates every transition.
- Introduce event sourcing for order status so the audit trail satisfies regulators and fulfilment teams, and so state can be rebuilt after an incident.
- Consume events from payment, inventory and returns rather than polling or joining.
- Cut over reads first for the five teams that query orders, then writes, keeping the monolith's order tables as a reverse-CDC projection.
- Reconcile order counts and monetary totals hourly against the monolith throughout the transition. A monetary mismatch is an immediate rollback, not a ticket.
- Load-test concurrent order state transitions at peak, since the state machine becomes the new serialisation point.
16. Keep the checkout transaction in the monolith for the first peak, and decide on the saga afterwards (depends on: 12, 13, 14, 15)
This is the deliberate difference from the obvious plan. Checkout is the single highest-risk cut and it sits directly on the peak-critical path. A distributed saga across pricing, inventory, payment and orders buys elegance at the cost of the two things the brief protects most: January and July sales.
- Thin the monolith's checkout into a synchronous orchestrator that calls the Pricing, Inventory, Payment and Order services through the gateway.
- Implement compensation inline in the orchestrator — a failed authorisation releases the reservation, a failed order creation voids the authorisation — without introducing a general saga framework.
- Propagate idempotency keys end to end so a retried checkout cannot double-charge or double-reserve.
- Handle the peak case explicitly: when inventory or pricing is slow, checkout must fail to a retryable state, never to a half-committed order.
- Require the peak-readiness gate before the cut that makes checkout depend on remote calls. A failed gate is a stop, not a delay; the monolith stays authoritative.
- Review after a full peak whether the orchestrator is worth extracting as a saga-based Checkout service. That decision belongs to the follow-up program, with peak data in hand.
- Document and sign off the deferral, so it is an accepted design choice rather than an unfinished step.
17. Migrate the back-office, storefront and mobile clients off the monolith database (depends on: 16)
Until the clients move, the monolith's database stays a dependency even where the logic has already left.
- Refactor back-office screens to consume service APIs through the gateway, replacing direct SQL access table by table, starting with orders and customers.
- Add aggregation endpoints where a screen needs several services, plus a short-lived cache so 300 staff do not multiply load on the new services.
- Update the server-rendered storefront to call service APIs while keeping the existing rendering path working behind a flag, so a rendering regression is a flag flip rather than a rollback.
- Point the mobile app at the gateway for migrated endpoints and keep the old endpoints alive for un-updated app versions. No version of the app in the field may break at any point in the program.
- Publish API versioning rules and deprecation windows so teams can change their services without coordinating with client releases.
- Load-test the back-office with 300 concurrent staff on top of peak storefront traffic, since the two now share services.
18. Decommission the extracted modules, validate the second peak, write the exit report (depends on: 17)
Removes what is left and proves the new architecture survives a peak. This step is as much about proving the state is coherent as about deleting code.
- Delete dead code and dropped tables module by module, only after a module has run a full peak or four clean weeks, whichever is longer.
- Keep read-only access to the old database for a defined period for historical and regulatory queries, then archive and decommission it.
- Replace the monolith's remaining cross-module reads with service calls or event-fed projections. The monolith should now be a small set of modules plus the checkout orchestrator.
- Re-run the full 12x load test against the new topology across all 8 countries, 3 currencies and 4 languages, and tune autoscaling, connection pools and broker partitions from the results.
- Run chaos game days: kill each service in turn and confirm the storefront degrades gracefully rather than failing completely.
- Confirm and publish the peak-readiness gate evidence before the second peak. A failed gate defers remaining work rather than risking the peak.
- Write the exit report: final service boundaries, data ownership, runbooks, SLO history, the scope-ladder rung actually reached, and the list of work explicitly deferred to a follow-up program.
--- PROPOSAL 3 ---
Proposal ID: 8a14de17-3842-4134-ba82-c6e281ddebf1
Content:
Estimated Complexity: high
Success Metrics: 1. Zero unplanned downtime during the 12-month migration and subsequent peaks.
2. Peak season (Jan/Jul) capacity maintained at 12x baseline with no performance degradation in checkout flows.
3. 100% of Pricing and Promotion transactions match the Golden Master characterization tests post-extraction.
4. Five teams deploying independently at least once per week without coordination conflicts.
5. All monolith-to-service data synchronization latency under 2 seconds (near real-time).
6. Database size reduced by >40% through extraction and cleanup of legacy unused tables.
7. Search index refresh time reduced from 24 hours (nightly) to < 1 minute (real-time).
Steps (16):
1. Program Governance, Peak Calendar, and Scope Ladder
Establish the binding constraints of the program before any technical work begins. The calendar dictates that the January and July sales peaks are immovable objects; therefore, all migration steps must be scheduled around them.
2. Platform Foundation: Kubernetes, Gateway, and Observability (depends on: 1)
Deploy the infrastructure layer required to run services independently and observe traffic flow. This includes a Kubernetes cluster for workloads, an API Gateway as the central routing control point, and a full observability stack (Tracing, Metrics, Logs). The Gateway is the primary mechanism for rollback via traffic shifting.
3. Data Foundation: CDC, Outbox Pattern, and Transactional Events (depends on: 1, 2)
Implement Change Data Capture (Debezium) and a Transactional Outbox pattern in the monolith. This creates the event backbone required for eventual consistency and allows new services to subscribe to monolith changes without touching the legacy code logic. This step runs in parallel with platform setup.
4. Architectural Decoupling: Table Ownership and Anti-Corruption Layer (depends on: 2)
Define strict ownership for the 350 tables and implement an Anti-Corruption Layer (ACL) to intercept cross-module dependencies. This involves creating separate database schemas or logical boundaries for high-coupling areas like Orders and Catalogue to prepare for physical separation.
5. Characterization Test Harness: The Golden Master (depends on: 2, 3)
Build a replay engine and capture a 'Golden Master' corpus of production traffic. This automated test suite records request/response pairs from the monolith, creating a baseline for validation. This is critical for the Pricing module and high-traffic endpoints where refactoring is impossible.
6. First Extraction Pilot: Catalogue and Search (Read-Heavy) (depends on: 3, 4, 5)
Extract the Catalogue and Search services. These are low-risk (read-heavy) and validate the strangler fig pattern. Implement real-time search indexing via CDC events, replacing the nightly Lucene rebuild. Use the Golden Master to verify product data and search results match the monolith.
7. Second Extraction: Inventory Synchronization (depends on: 3, 5)
Extract Inventory management, specifically handling the integration with the external warehouse system (15-minute sync). This removes a critical dependency from the monolith and enables real-time stock visibility. The service acts as the single source of truth for stock levels.
8. Third Extraction: Customer Profile and Identity (depends on: 3, 4)
Extract Customer Accounts and Profile management. Move authentication logic and customer data ownership to a dedicated service. Ensure the Mobile App and Storefront can authenticate against the new service while maintaining session compatibility via JWT or shared session state.
9. Pricing Module Stabilization: Black Box Extraction (depends on: 5)
Extract the 200,000 LOC Pricing and Promotions module as a 'Black Box' service. Do not refactor the logic; wrap it. Use the Golden Master to validate 100% accuracy across all 8 countries and complex promotion rules. This step is strictly scheduled outside of any peak season.
10. Core Transactional Extraction: Orders and Order Management (depends on: 6, 7, 8, 9)
Extract the Order Management domain, including order creation, state machines, and lifecycle tracking. This service acts as the consumer of events from Inventory, Pricing, and Customer services. It replaces the monolith's direct order processing logic.
11. Checkout Orchestration and Saga Implementation (depends on: 7, 9, 10)
Implement the Checkout Service, acting as the orchestrator (Saga) for the payment process. It coordinates the distributed transaction across Cart, Pricing, Inventory, and Payments. It handles compensating transactions (e.g., releasing inventory on payment failure) to ensure data consistency.
12. Payment Provider Integration Service (depends on: 10, 11)
Extract the logic responsible for connecting to the three payment providers. This service handles authorization, capture, and refunds. By isolating this, the monolith no longer holds sensitive payment processing logic, reducing PCI scope and coupling.
13. Return and Refund Workflow Extraction (depends on: 10, 12)
Extract the Returns and Refunds logic. This service consumes order events to trigger return workflows, updates inventory, and requests refunds from the Payment Service. This completes the reverse logistics capability as a microservice.
14. Legacy Monolith Decommissioning: Strangler Finish (depends on: 10, 11, 12, 13)
Remove the extracted logic from the monolith. The monolith is now a legacy shell containing only the storefront rendering layer (which delegates to APIs) and potentially the Back-Office (if not yet migrated). This step involves rigorous cleanup of unused code and database tables.
15. Back-Office Migration and Staff Tooling (depends on: 14)
Migrate the Back-Office (300 staff users) to use the new service APIs. This may involve a dedicated BFF (Backend for Frontend) service that aggregates data from Orders, Customers, and Inventory for the staff UI, replacing direct database joins in the monolith.
16. Operational Handover and Autonomous Team Setup (depends on: 15)
Finalize team ownership. Each of the five teams is assigned to specific services (e.g., Team A owns Inventory and Search, Team B owns Orders and Checkout). Transfer on-call rotations and disaster recovery runbooks to the new services.
Instructions:
1. Carefully evaluate each proposal considering:
- Clarity and detail of the proposed steps.
- Overall alignment with the Main Objective.
- Quality and relevance of the proposed success metrics.
- Coherence of dependencies between steps (if any).
2. Think deeply about each proposal, analyzing its strengths and weaknesses. Consider how well each proposal addresses the main objective and which one would be most effective.
After your thorough analysis, give the Proposal ID of the selected proposal and a one- or two-sentence justification of your choice.
Answer with a single JSON object, and nothing else, that conforms to this JSON schema:
{"description": "What a voting agent must answer with.", "properties": {"selected_proposal_id": {"title": "Selected Proposal Id", "type": "string", "enum": ["eaa6af3c-28c3-480e-b9b1-be2c22215422", "2a819ee6-3a8b-48c8-a67f-7bcb82c07659", "8a14de17-3842-4134-ba82-c6e281ddebf1"]}, "justification": {"title": "Justification", "type": "string"}}, "required": ["selected_proposal_id", "justification"], "title": "VoteAnswer", "type": "object", "additionalProperties": false}
{"selected_proposal_id": "eaa6af3c-28c3-480e-b9b1-be2c22215422", "justification": "Proposal 1 is the most complete and internally coherent: its 20 dependency-linked steps cover platform, data (CDC/outbox/four-stage cutover), seam-level verification, rollback automation, chaos testing and explicit peak-readiness gates, and its success metrics are the most precise and measurable (pricing parity on 1M+ requests, reconciliation thresholds, rollback <30 min, 12x peak SLAs). It also matches the brief's core constraints—calendar-first scheduling, no feature freeze, reversible every step, and protected January/July peaks—without the thinner coverage seen in Proposal 3. Proposal 2 is a strong contender with a sensible deferral of the checkout saga, but Proposal 1's greater depth and explicit rollback/reconciliation machinery make it the safer, more complete plan."} |
| qwen3.8-flash_voter_3 | qwen3.8-flash · alibaba/qwen3.8-flash |
Proposal B · deepseek-flash_refine_2 | Proposal 2 is superior because it correctly identifies that a full distributed checkout extraction cannot realistically survive the January and July peak seasons within a 12-month window. By deliberately keeping the checkout transaction inside the monolith as a synchronous orchestrator for the first year, it perfectly aligns with the non-negotiable requirement to preserve peak capacity and avoid unplanned downtime during sales, whereas Proposal 1's timeline is dangerously optimistic and Proposal 3 lacks the necessary architectural detail and risk mitigation strategies. |
19.0k in · 2.3k out · 32 s | show[SYSTEM]
You are an expert and objective evaluator of project plan proposals.
Your task is to select the BEST proposal based on criteria of completeness, clarity, and alignment with the main objective.
Use your internal reasoning processes to thoroughly analyze each proposal, considering all aspects and implications.
Take as much time and space as you need to evaluate each proposal in depth before making your decision.
Every text field you write will be read by a busy person, so write for them: short sentences, one idea each, in short paragraphs. Text fields accept Markdown: separate paragraphs with a blank line, use a bullet list when you enumerate things and plain paragraphs when you explain or argue, and bold at most one key phrase per paragraph. A text of more than three sentences must be split into paragraphs; never deliver a single unbroken block of text.
[HUMAN]
Main Objective: "A mid-size European fashion retailer runs its e-commerce on a 10-year-old monolith: Java 8 / Spring, about 2 million lines, one PostgreSQL database of 1.2 TB with 350 tables and heavy use of stored procedures and cross-module joins. It serves 8 countries, 3 currencies and 4 languages, with about 40,000 orders a day and peaks of 12x during sales. The monolith contains: the storefront (server-rendered, plus a separate mobile app hitting the same endpoints), catalogue and search (a Lucene index rebuilt nightly), pricing and promotions (the most complex module, 200,000 lines, with country-specific rules nobody fully understands), cart and checkout with three payment providers, order management, inventory synchronised every 15 minutes with the warehouse system via file exchange, customer accounts and loyalty, returns, and a back-office used by 300 staff. Deployments happen every two weeks as a single artefact with a 30-minute maintenance window; test coverage is 25% and mostly unit tests. Five teams of 8 developers, each organised around a business area but all committing to the same repository.
Plan the migration to independently deployable services over 12 months with no feature freeze, no unplanned downtime and the ability to roll back every step, preserving the peak-season capacity (sales in January and July must not be put at risk)."
Proposals to Evaluate:
--- PROPOSAL 1 ---
Proposal ID: eaa6af3c-28c3-480e-b9b1-be2c22215422
Content:
Estimated Complexity: high
Success Metrics:
- **Zero unplanned downtime**: 100% availability throughout 12-month migration (excluding planned 30-min blue-green deployments); no production incidents attributable to migration architecture
- **Peak seasons protected**: January and July peaks (480k orders/day) sustain zero degradation caused by migration; checkout p99 ≤ 5 seconds, payment authorization ≤ 2 seconds, error rate ≤ 0.5%, no queue backlog > 5 minutes
- **Independent deployability**: All eight services independently deployable by month 12; each team releases on own cadence (weekly or faster) with zero cross-team deployment coordination; 100% of service releases verified rollback-capable in < 30 minutes
- **Rollback-proven**: Every production increment has rehearsed, documented, tested rollback path (expand/contract migrations, feature flags, reverse CDC); monthly chaos game days validate rollback procedures; zero increments reach production without passing rollback gate
- **Data consistency**: Hourly reconciliation shows < 0.001% row-count and checksum discrepancy between service databases and monolith (pre-decommissioning); zero business-invariant violations (no duplicate orders, no lost payments, no inventory oversells)
- **Pricing correctness**: 100% agreement between new Pricing service and golden-master corpus across 1M+ historical requests covering all 8 countries, 3 currencies, 4 languages, all promotion types; zero pricing errors post-cutover
- **Search freshness**: Product availability reflects in search within < 60 seconds of inventory change (vs. nightly rebuild); search latency p95 unchanged or improved at peak load
- **Warehouse sync improvement**: Inventory synchronization lag reduced from 15 minutes to < 2 minutes end-to-end; 100% of daily warehouse updates processed; no missed sync cycles during migration
- **Payment processing**: Zero regressions with all three payment providers; fraud detection active and effective; PCI-DSS compliance maintained; idempotency prevents duplicate charges; payment success rate ≥ 99.5% at peak
- **Back-office operations unaffected**: All 300 staff seamlessly using service APIs; service aggregation endpoints maintain p95 latency ≤ 500 ms; bulk operations (refunds, order status updates) complete within SLA
- **Test coverage for services**: All newly written service code reaches 80%+ line coverage; golden master validates 100% of public API contracts before production traffic; contract tests (Pact) prevent breaking changes between services
- **Peak-readiness gate passed**: Six weeks before each peak (mid-November, mid-May), gate published showing 12x load test results, capacity headroom, rollback rehearsal duration, and SLO status; failed gate defers work; evidence published publicly
- **Team independence by month 12**: Five teams deployed independently; each owns service codebase, pipeline, database schema, on-call rotation, SLOs; no cross-team pull requests blocking releases; internal developer platform (golden-path templates, self-service deployments) adopted by all teams
- **Scope ladder completed**: Rungs 1–6 reached by month 12 (or deliberately stopped at rung boundary with documented justification); all services proven at peak; monolith reduced to < 5% or decommissioned
- **Calendar adherence**: No major extractions or refactors during freeze windows (Dec 1–Jan 15, June 1–July 15); all production increments land in open windows with minimum 4-week soak before freeze; timeline published and adhered to
- **Event-driven architecture validated**: Kafka message broker handles 480k+ messages/day at peak; no message loss, no ordering violations; outbox pattern ensures every domain event persists atomically
- **Fallback capacity maintained**: Monolith rollback path kept warm and functional (receiving live traffic or ready-to-receive via feature flag) until each service survives one full peak; no service extracted without proven rollback capability
Steps (20):
1. Program Setup, Scope Ladder, Organizational Model, and Peak-Safe Calendar
Establishes the governance framework and constraints that all later work obeys. The calendar is the binding constraint—January and July peaks must not be put at risk—so it is decided first, before any technical choices.
**Inception and Baselines**: Run a two-week inception to establish current state: build time, deployment lead time, change failure rate, MTTR per team, module-change frequency, database load profiles (all measurable, not asserted).
**Calendar and Freeze Windows**: Declare hard freezes from December 1–January 15 and June 1–July 15; only rollback-enabling and hardening changes allowed during freezes. Confirm two open delivery windows per year (February–May and August–November); all migration work must fit these windows. No change on checkout path lands within four weeks of a freeze.
**Scope Ladder**: Define ranked rungs 1–6 that deliver the core objective; rungs 7+ are optional. Slippage means stopping at a rung boundary, never mid-increment. Rungs: 1. Platform ready. 2. Search extracted and proven. 3. Returns and Inventory proven at low stakes. 4. Payment and Orders stable. 5. Checkout orchestration live and soaking. 6. Back-office migrated, monolith core reduced.
**Organizational Model**: Define service-aligned teams (Search, Orders, Inventory, Payments, Customer, Fulfillment) with clear ownership, on-call rotations, and SLOs per service. Each team owns codebase, pipeline, database schema, and incidents by month 6. Transition plan: teams split duties (monolith maintenance + service) until month 3, then shift to service-primary by month 6.
**Rollback Charter**: Every increment ships an expand/contract database change, a feature-flag kill switch, and a recorded game-day rehearsal. No go-live without tested rollback in < 30 minutes.
**Peak-Readiness Gate**: Define gate to run six weeks before each peak (mid-November, mid-May): 12x load test, capacity headroom check, rollback rehearsal, error-budget review. Gate is pass/fail; failed gate defers work to next window.
**Capacity Budget**: Allocate 40–50% of five teams' capacity for migration; staff scope ladder to fit capacity, not to fill the year. Create migration enablement squad of six rotating engineers to own platform, shared cuts, and risky data work.
2. Executable Architecture Map, Table Ownership, and Boundary Enforcement (depends on: 1)
Produces an architecture map that the build itself enforces. Five teams in one repo will silently re-couple anything separated if not policed, so enforcement is embedded in the map.
**Real Coupling via Tracing**: Instrument monolith with distributed tracing; let it run four weeks to capture real call paths—static imports miss true coupling.
**Table Ownership Matrix**: Parse every SQL statement, ORM mapping, and stored procedure; cross-check against database query logs. Build table-to-module and query-to-module map. Assign every 350 table to exactly one owning module; tables nobody can own are 'contested' and scheduled into data work (Step 7).
**Scoring and Extraction Sequence**: Score each candidate service on coupling, transactional risk, change frequency, and peak-path criticality. This ranking (not intuition) drives extraction order.
**Enforcement via Automation**: Add ArchUnit rules to CI to fail builds on new cross-module Java dependencies (existing violations frozen in baseline that may only shrink). Add SQL linter to CI to fail on cross-module joins and cross-module writes (same shrinking baseline). Violations tracked weekly in architecture review.
**Stored Procedure Audit**: Inventory all stored procedures; attribute to owning module; plan move into module code or leave as module-private function. No stored procedure may touch two modules' tables post-extraction.
**Architecture Decision Records**: Publish target service list, owning team per service, and reasoning as ADRs.
**Mid-Program Review**: Hold review at month 6 to re-rank scope ladder using what the map actually revealed. This is the one planned re-planning point of the program.
3. Delivery Platform: Per-Service Pipelines, Gateway, Feature Flags, and Environments (depends on: 1, 2)
Builds the delivery and traffic machinery that makes every later step reversible. No service is extracted until its team can deploy, flag, and route independently.
**Kubernetes and Namespaces**: Extend platform on Kubernetes (or existing container platform) with one namespace per service, quotas, and autoscaling sized for 12x peak (480k orders/day). Establish dev/staging/prod with strict resource isolation.
**API Gateway**: Deploy API gateway (Kong, AWS ALB) in front of monolith as strangler entry point. Storefront, mobile app, and back-office traffic flow through gateway from day one, even while routing everything to monolith. Gateway enforces rate limiting, bulkheads, timeouts, and circuit breakers.
**Feature-Flag Service**: Deploy centralized feature-flag system (LaunchDarkly, Unleash). Require every new call path to be flag-guarded. Flags are the primary rollback instrument; changes to traffic routing require no code deployment.
**Per-Module CI/CD Pipeline**: Give every module its own independent CI/CD pipeline and environment. Monolith keeps current pipeline for hotfixes until Step 5 replaces it. Pipeline includes automated security scanning, performance baselines, and contract-test gates.
**Secrets and Configuration**: Introduce secrets management (Vault) and per-environment configuration. Behavioral changes require no monolith redeploy.
**Golden-Path Templates**: Define reusable templates for new services: build layout, Dockerfile, pipeline stages, observability instrumentation, health checks, feature-flag integration, database migration tool. Extraction starts from template, not blank page.
**Permanent Environments**: Reserve two full-size environments: (1) production-like soak environment for multi-week stability validation, (2) load-test environment capable of 12x traffic generation against production-shaped data (8 countries, 3 currencies, 4 languages, realistic product catalog).
4. Observability, Business SLOs, Error Budgets, and Automated Rollback Controller (depends on: 3)
Makes the system observable so canaries are judged automatically and reverted without human guessing. This is the prerequisite for rollback promises in all later steps.
**Observability Foundation**: Deploy centralized logging (ELK/Loki), metrics (Prometheus/Grafana), and distributed tracing (Jaeger) with trace correlation working across gateway, monolith, and every new service from day one.
**Blind-Spot Instrumentation**: Instrument monolith's unmeasured aspects: query latency by module, connection-pool saturation, Lucene rebuild duration, warehouse file-exchange lag, stored procedure execution time, lock contention.
**Business SLOs**: Define SLOs on business outcomes, not infrastructure:
- Checkout success rate ≥ 99.5%
- Order confirmation latency p99 ≤ 5 seconds at baseline (40k orders/day) and peak (480k orders/day)
- Search result latency p95 ≤ 1 second
- Payment authorization latency ≤ 2 seconds
- Price computation latency ≤ 200 ms
- Warehouse sync freshness ≤ 2 minutes end-to-end (vs. current 15 minutes)
- Cross-module data consistency: hourly reconciliation shows < 0.001% row-count discrepancy
**Error Budget and Rollback Policy**: Attach error budget to each SLO. When a service burns budget (or latency diverges > threshold during canary), its rollout stops automatically and flags revert without negotiation. Document policy explicitly; use during peaks without exception.
**Automated Rollback Controller**: Build system that monitors error rate and latency divergence during canary. On breach, gateway shifts traffic back and flags disable automatically. Fallback requires no human intervention. Test this automation in monthly game days.
**Dashboards**: Create per-service dashboards readable by tired engineers at 3 AM (traffic, errors, latency p50/p95/p99, database load). Create program dashboard showing progress against scope ladder, rung by rung.
5. Pricing Module: Rules Catalog and Golden-Master Characterization (Parallel with Data Platform) (depends on: 1, 2)
Catalog the 200k LOC pricing engine behavior before any extraction attempt. This is the foundational risk mitigation for the most complex module; it runs in parallel with data platform work (Step 7) because it is independent of infrastructure.
**Rules Discovery and Documentation**: Analyze and document all pricing rules in scope: country-specific logic (8 countries), currency handling (3 currencies), promotional rules, seasonal pricing, bulk discounts, loyalty point applications, regional variations. Create a living rules inventory.
**Historical Request Corpus**: Capture at least 1 million real historical pricing requests from production logs, covering all 8 countries, 3 currencies, 4 languages, all promotion types discoverable, edge cases, peak-season variations. Record exact inputs and outputs.
**Golden-Master Characterization Suite**: Build automated harness to replay corpus against monolith, capturing deterministic responses. This suite is the 'golden master': any new pricing service must match 100% of outputs. Suite becomes the automated gate for pricing extraction (Step 14).
**Test Data Expansion**: Supplement historical data with synthetic edge cases: multi-currency conversions, minimum purchase thresholds, conflicting promotions, time-based seasonal rules, inventory-driven pricing, customer-segment overrides.
**Dependency Mapping**: Explicitly document which customer attributes, product attributes, inventory levels, time-based factors, and external parameters affect pricing. Identify all cross-module dependencies that pricing currently reads from monolith (e.g., customer loyalty status from Customer module, product hierarchy from Catalogue module).
**Baseline Validation**: Run golden master against monolith to establish baseline passing rate. Document any non-deterministic behavior or race conditions found. This baseline is locked; no drift allowed during migration.
**CI Gate Definition**: Define hard rule: pricing service extraction cannot proceed until characterization tests pass 100% against both monolith and new service. Any divergence blocks ramp. This gate is not negotiable.
6. Seam-Level Verification: Golden Master, Contracts, Shadow Diffing, and Reconciliation (depends on: 2, 3)
Replaces impossible goal of blanket test coverage with verification exactly at the cut point. A 2M-line monolith cannot reach 70% coverage in a year; a service boundary can be verified to very high standard in weeks.
**Characterization Harness for All Services**: Build framework to record real production requests (anonymizing PII) and replay against monolith. Capture full responses as golden master. Every extracted service must pass golden master on its public API before taking live traffic. Output a diff report, not pass/fail.
**Consumer-Driven Contracts (Pact)**: Require contracts between monolith and each new service, and between services themselves. A change on one side breaks a build instead of waiting for production. Contracts versioned; breaking changes trigger explicit communication plan.
**Shadow Traffic and Response Diffing**: Mirror live requests to new service; compare responses field by field (not just status codes). Measure divergence rate continuously. Gate traffic ramp on divergence < 0.01% for 48 hours.
**Per-Module Data Reconciliation**: Build data reconciliation as first-class test, not afterthought. Compare row counts, checksums, and business invariants on hourly schedule. Owner assigned; alert threshold set. Reconciliation runs continuously during transition period (Stages A–C of cutover playbook).
**Synthetic Canary Transactions**: Implement real checkout, return, and search transactions executing every few minutes. Alert on functional regression before customers notice. Include multi-country, multi-currency variations.
**Explicit Non-Goal**: Do not pursue blanket line coverage of monolith. Track coverage only for newly written service code, target 80%. Seam-level verification replaces this impossible goal.
7. Data Platform: Schema Ownership, Join Elimination, CDC, Transactional Outbox, and Four-Stage Cutover Playbook (depends on: 2, 3)
The hardest and most under-specified part of most migrations. This work is independent of service extraction, so it starts in month 1 and runs in parallel. It is the foundation for reversible data transitions.
**Database-Enforced Ownership**: Assign every PostgreSQL table to exactly one module. Create one role per module, able to write only its own schema and to read others only through defined views. Database rejects cross-schema writes at the engine level, not by convention. Test this enforcement in CI.
**Stored Procedure Refactoring**: Inventory every stored procedure, attribute it to owning module. Either move logic into that module's application code or leave as module-private database function. After extraction, no stored procedure may touch two modules' tables.
**Cross-Module Join Elimination**: Eliminate cross-module joins one at a time, replacing each with an API call (preferred during cutover), an event-fed materialized read model, or a duplicated read-only projection. Track count per module; drive to zero before that module is extracted.
**Change Data Capture (CDC)**: Deploy Debezium reading PostgreSQL WAL into Kafka. This publishes monolith domain events with zero application change—lowest-risk start possible. Configure per-table CDC; test at peak load (480k events/day during 12x peak).
**Transactional Outbox Pattern**: For all new services, add outbox table. When service writes business state, it writes domain event atomically in same transaction. Outbox relay publishes to Kafka, ensuring no event loss. Implement poison-pill handling for failed publishes.
**Four-Stage Cutover Playbook (Reusable)**: Define one playbook applied identically every service extraction:
- **Stage A** (Shadow-Read): Service owns schema logically, reads from CDC into its own store, serves shadow traffic only. Monolith remains system of record; no cutover yet.
- **Stage B** (Read Cutover): Reads cut over to new service via flag. Monolith stays system of record via reverse-CDC replication. Rollback is flag flip + reconciliation pass.
- **Stage C** (Write Cutover): Writes cut over to new service. Monolith tables become read-only replicas fed by reverse CDC from service. Rollback is configuration change (flip sync direction) + reconciliation, not data restore.
- **Stage D** (Deletion): Old tables and dead code dropped only after module has survived one full peak (January or July) or four clean weeks, whichever is longer. Maintain 90-day read-only archive of old tables for regulatory retention and emergency queries.
**Reconciliation Service**: Build now (not later) so every cutover has objective consistency check. Compare row counts, business-invariant checksums, monetary totals hourly. Owner assigned; thresholds set. Mismatch is immediate rollback signal.
**Storage Migration Timeline**: New services start on existing cluster with own schemas. Physical database split (move to separate cluster) happens only once module is stable and proven at peak. This removes a critical-path blocker and allows parallelization.
8. Extract Catalogue and Search: Read-Heavy Pilot Service (depends on: 5, 6, 7)
First extraction, chosen because it is read-heavy, isolated, and carries no transactional risk. It also pays for itself: replacing nightly Lucene rebuild with real-time indexing is a visible business win that buys political cover for harder cuts.
**New Catalogue Service**: Create service owning product, category, media, and attributes tables. Build search API using Elasticsearch/OpenSearch with real-time indexing.
**CDC Feed**: Subscribe to CDC stream from monolith. ProductUpdated, PriceChanged, InventoryUpdated events trigger real-time search index refresh. Product availability reflects in search within < 60 seconds of change (vs. nightly rebuild).
**Shadow Traffic and Diff Validation**: Route requests through gateway behind feature flag. Run shadow mode: send requests to both monolith Lucene and new Search service; compare result sets field by field. Measure divergence; require < 0.01% for 48 hours before traffic ramp.
**Gradual Traffic Ramp**: 1% → 5% → 25% → 50% → 100% using feature flags and canary deployments. Rollback controller monitors latency and error rates; reverts flag if breach. Keep old Lucene index warm for two weeks post-cutover as rollback target.
**Mobile App Verification**: Verify mobile app behavior explicitly; it hits same endpoints. Test session persistence, offline search cache behavior, and app version compatibility during ramp.
**Four-Stage Playbook**: Execute Stages A–D as defined in Step 7. Stage A (shadow) lasts 1 week minimum. Stage B (read cutover) lasts 2 weeks. Stage C does not apply (reads only). Stage D (cleanup) after one peak or four weeks.
**Soak Period**: Land this extraction in open delivery window; soak at least four weeks before freeze (Dec 1 or June 1). No extraction reaches production less than four weeks before a freeze.
9. Extract Returns: Low-Stakes Proof of Four-Stage Playbook (depends on: 5, 6, 7)
Second extraction and first write-path proof. Returns is chosen because it is off peak-critical path, has modest coupling, and exercises full four-stage playbook at low risk. Primary output is a proven, reusable procedure, not just one service.
**Returns Service**: Build with own schema. Consume order and customer events rather than joining their tables. Implement return state machine: Requested → Approved → Shipped → Received → Refunded.
**Full Four-Stage Execution**: Apply Stages A–D end-to-end with explicit recorded game day validating each stage rollback path. Stage A (shadow reads) for 1 week. Stage B (read cutover) for 2 weeks. Stage C (write cutover) with reverse CDC. Stage D (cleanup) after one peak or four weeks.
**Rollback Rehearsal**: Before write cutover, execute full game day: simulate service failure mid-cutover, trigger rollback (reverse CDC, flag flip, reconciliation), verify all data consistent, re-run golden master, confirm back-office queries still work. Record this session; play back monthly.
**Back-Office Screens**: Keep back-office returns screens on monolith for now (staff workflow untouched). Returns service is API-only; back-office integration comes later (Step 18).
**Friction Point Capture**: Record every operational friction, process gap, and test hole discovered during extraction. Update playbook from learnings. This step is as much about process validation as about extracting Returns.
**Soak and Timing**: Execute in open window; soak returns service for minimum four weeks before any freeze. Gate to proceeding to Inventory (Step 10) is successful four-week soak with zero rollbacks and full reconciliation agreement.
10. Extract Inventory: Warehouse Sync Improvement and Reservation Semantics (depends on: 5, 6, 7)
Removes one of sharpest coupling points (15-minute file-exchange lag) and unblocks checkout work. Inventory runs in parallel with returns because it couples monolith to external warehouse system, not to other modules.
**Inventory Service**: Ingest warehouse feed directly (SFTP/API) instead of monolith polling. Design reservation semantics now: Reserve (place hold), Confirm (finalize after order), Release (cancel reservation on timeout/failure), with explicit timeout windows. Own stock levels and reservations per product per location.
**Parallel Feeds During Transition**: Run new ingest in parallel with legacy 15-minute feed. Reconcile hourly until both agree. This validates the new ingest does not miss updates or duplicate changes.
**Monolith Inventory Tables as Projection**: Keep monolith's inventory tables as read-only replicas fed by CDC from new service during Stage C (write cutover). Cart and checkout continue calling monolith queries unchanged during cutover; no checkout changes yet.
**Four-Stage Execution**: Apply Stages A–D. Stage A (shadow ingests and reads) for 2 weeks (must survive two 15-minute sync windows and validate no drift). Stage B (read cutover) for 2 weeks. Stage C (write cutover) with reverse CDC. Stage D (cleanup) after one peak.
**Peak-Load Testing**: Load-test inventory ingest at 12x (400k SKU updates/day during peak). Warehouse feed schedule and sales peaks do not always align; test worst-case concurrency. Validate no reservation deadlocks, no stock over-sells.
**Cutover Order**: Inventory read cutover must complete before Cart extraction (Step 13) to avoid monolith checkout calling new Inventory service via internal API during transition.
**Soak and Gate**: Soak minimum four weeks before freeze. Gate to proceeding to Customer (Step 11) is four-week soak with zero reconciliation mismatches and warehouse feed lag improved to < 2 minutes.
11. Extract Customer Accounts and Loyalty: Conservative Authentication Strategy (depends on: 9, 10)
Extracts customer identity, profile, and loyalty programs. Authentication is deliberately placed late and guarded hardest because auth failures derail e-commerce migrations most often.
**Customer Service**: Own profile, address, and loyalty tables. Implement country-specific loyalty rules (8 countries, different point accrual rates) as data-driven rules where possible, code where not. Design API: GetCustomer, UpdateProfile, GetLoyaltyBalance, RedeemPoints, AccruePoints.
**Authentication Strategy Phase 1**: Keep authentication (login) in monolith for now. Customer service exposes only data APIs; token issuance remains monolith's responsibility. This delays risky auth cutover; less risk to peak season.
**Distributed Session Handling**: Introduce Redis-backed distributed sessions. Services can verify customer identity without querying monolith database. Implement token-validation API so services can verify bearer tokens without round-tripping to monolith.
**Data Cutover**: Execute four-stage playbook. Stage A (shadow reads) for 1 week. Stage B (read cutover) for 2 weeks. Stage C (write cutover) for new customers, address updates, loyalty accrual. Stage D (cleanup) after one peak.
**Golden Master for All Countries**: Golden master captures customer queries across all 8 countries, all 4 languages, and all loyalty-rule variations. Shadow-traffic diff must show < 0.01% divergence before read cutover.
**Mobile App Session Behavior**: Test mobile app's long-lived sessions explicitly; storefront does not hold sessions same way. Validate token refresh, session timeout, and app version compatibility during cutover.
**Loyalty Accrual Last**: Move loyalty point accrual and redemption last within this step (Stage C final substep). Loyalty error is customer-visible financial error, not technical incident; guard hardest.
**Soak and Gate**: Soak minimum four weeks. Gate to proceeding to Cart (Step 13) is successful loyalty accrual cutover with zero customer complaints and full reconciliation agreement.
12. Extract Cart: Stateful Session Service (depends on: 6, 7, 10, 11)
Extract shopping cart, which is stateful and sits directly in front of checkout. Extracted before Pricing and Checkout because both depend on stable Cart boundary.
**Cart Service on Redis**: Build on Redis (or PostgreSQL with session affinity) for session and line-item state. Validate products and inventory through service API calls rather than direct database joins. Design API: AddItem, RemoveItem, UpdateQuantity, GetCart, ApplyCoupon, ClearCart.
**Idempotent Operations**: Every cart operation is idempotent. Retried add during peak does not duplicate line item. Retried remove is safe. Implement via unique constraint on (session, sku) or idempotency-key header.
**Monolith Cart Tables as Projection**: Keep monolith's cart tables as read-only projections fed by CDC from Cart service. Back-office screens continue reading old cart tables for abandoned-cart analytics (not yet migrated to service APIs in this step).
**Four-Stage Execution**: Apply Stages A–D. Stage A (shadow reads) for 1 week. Stage B (read cutover) for 2 weeks (use feature flag; gradual ramp 10% → 50% → 100%). Stage C (write cutover to service); Stage D after one peak.
**Business Metric Monitoring**: Cart latency surfaces as lost revenue (abandonment), not just error logs. Track cart abandonment rate and add-to-cart latency as primary success metrics during ramp.
**Anonymous vs. Authenticated Carts**: Test both paths separately; they follow different session-tracking mechanisms and fail in different ways. Ensure cart persists across login boundary.
**Soak Before Freeze**: Land in open window; soak minimum four weeks before freeze (Dec 1 or June 1). Gate to proceeding to Pricing (Step 14) is four-week soak with cart abandonment rate unchanged or improved and zero lost transactions.
13. Extract Pricing as Black Box Using Golden-Master Validation (depends on: 5, 6, 7)
Extract 200k LOC pricing logic as-is without rewriting. Rules are not understood by anyone, so wrap and characterize rather than refactor. Rule decomposition deferred to follow-up program in writing.
**Wrap Without Refactor**: Move pricing code into dedicated service, unchanged. Service owns pricing tables post-cutover. Expose single decision API: ComputePrice(customerId, productId, locationId, timestamp, quantityId, loyaltyStatus) → {price, applicablePromotions, taxes, currency}.
**Dependency Injection for Reads**: Refactor pricing's dependencies so it obtains customer data via Customer service API, product data via Catalogue service API, inventory via Inventory service API. No direct cross-module database joins.
**Golden-Master Validation**: Run characterization test suite (built in Step 5) against new service. Require 100% output match on all 1M historical requests across all 8 countries, 3 currencies, 4 languages, all promotion types, edge cases. Any divergence blocks ramp; no exceptions.
**Shadow Mode Duration**: Run shadow traffic against live pricing requests for minimum four weeks, comparing every computed price with monolith. Measure divergence continuously. Divergence > 0.001% blocks ramp.
**Gradual Cutover by Country**: Cut over per-country rather than all-at-once. Start with lowest-revenue country, validate four weeks per country, then ramp to others. Per-country flags allow independent rollback.
**Rollback Path**: Keep monolith's pricing evaluator available and warm as rollback target for at least one full peak (January or July) after cutover. Maintain ability to flip back to monolith pricing via feature flag without data restore.
**Four-Stage Playbook**: Stages A–D applied to pricing tables. Stage A (shadow) 4+ weeks. Stage B (read cutover) 2 weeks per country. Stage C (write cutover) per country. Stage D (cleanup) after one full peak.
**Deferred Refactoring in Writing**: Publish decision that pricing rule decomposition, DSL, and optimization are explicitly deferred to follow-up program after this migration stabilizes. Include this in all project communications and retrospectives.
14. Extract Payment: PCI-Strict Regime and Provider-by-Provider Cutover (depends on: 5, 6, 7)
Extract payment processing with stricter regime than any other service. Mistakes are irreversible and regulatory. Extracted before checkout orchestration because checkout cannot be decomposed without payment boundary.
**Payment Service**: Own integration with three payment providers (tokenization, authorization, capture, refund, provider webhooks). Design API: AuthorizePayment(idempotencyKey, amount, currency, cardToken, customerId) → {authorizationId, status}; CapturePayment(authorizationId); RefundPayment(captureId); HandleWebhook(webhookPayload).
**PCI Scope Reduction**: No raw card data at rest in service. Card data flows directly from client to provider (tokenization); only tokens stored in Payment service. Credentials in secrets management (Vault). No card data in logs or distributed traces.
**Idempotent Operations**: Explicit idempotency-key handling. Every payment request is idempotent; retries at peak are normal and must not double-charge. Implement via idempotency-key deduplication store (Redis with TTL).
**Provider-by-Provider Cutover**: Cut over one provider at a time (start with lowest-volume provider). Stage A (shadow) 2 weeks per provider. Stage B (read cutover, not applicable). Stage C (write cutover) for each provider, maintain fallback to monolith for other providers. Test each provider's decline, timeout, 3-D Secure, and chargeback scenarios explicitly.
**Golden Master Scenarios**: Golden master covers all three providers, all decline reasons, timeouts, partial authorizations, refund scenarios, chargebacks. Shadow traffic compares full payment outcomes (authId, status, amount, timestamp) before any live provider cutover.
**Fraud Detection and 3-D Secure**: These paths are usually least-tested and most visible when broken. Test explicitly; goldne master includes fraud-decline and 3-D Secure flows. Verify fraud rules and thresholds carry over unchanged.
**Fallback Orchestration**: Monolith retains ability to handle payment directly (as fallback) until second peak after Payment service cutover. Checkout can gracefully degrade to old payment path via feature flag if new service fails.
**Four-Stage Playbook**: Stages A–D per provider. Stage C (write) is highest-risk; ensure golden master passes 100% and shadow mode shows zero divergence before each provider cutover. Gate and soak strictly: four weeks minimum before any freeze.
**Soak and Timing**: Land in open window (Feb–May or Aug–Nov). Complete all three providers' Stage C cutover by month 9 to allow checkout orchestration time to soak before freeze.
15. Extract Orders: Event-Sourced Record of Truth (depends on: 9, 13, 14)
Extract order management as authoritative record of order lifecycle. Extracted after Inventory, Pricing, and Payment exist and are stable, because Orders depends on all three.
**Orders Service**: Own order tables and order state machine. Implement explicit state transitions: Pending → Confirmed → Preparing → Shipped → Delivered, with validation blocking invalid transitions. Design API: CreateOrder(cartId, customerId, paymentAuthorizationId), GetOrder(orderId), CancelOrder(orderId), UpdateOrderStatus.
**Event Sourcing**: Record all order state changes as immutable events. Build order state from event log on demand. Audit trail satisfies regulators and fulfillment teams; state can be rebuilt after incidents. Include: OrderCreated, PaymentAuthorized, InventoryReserved, OrderConfirmed, OrderPreparing, OrderShipped, OrderDelivered, OrderCancelled.
**Event Consumption**: Consume events from Payment service (PaymentAuthorized, PaymentFailed), Inventory service (StockReserved, ReservationCancelled), and Returns service (ReturnInitiated, RefundIssued) rather than polling or joining.
**Four-Stage Playbook**: Stages A–D. Stage A (shadow) for 1 week. Stage B (read cutover) for 2 weeks, with gradual flag ramp. Five teams that query orders start reading from Orders service via API. Stage C (write cutover): new orders written to Orders service; monolith order tables become reverse-CDC read-only replicas. Stage D after one peak.
**Reconciliation: Monetary and Row-Count**: Reconcile order counts and monetary totals hourly against monolith throughout transition. Currency totals must match exactly (cent-by-cent); row count discrepancies are immediate rollback. Implement automated reconciliation query; owner assigned; threshold zero.
**Concurrent Order Transitions**: Load-test concurrent order state transitions at 480k/day peak. Order state machine becomes serialization point for distributed system; ensure no race conditions, no duplicate orders, no lost transactions.
**Soak Before Checkout**: Complete Orders cutover (Stages A–C) by month 9. Soak minimum four weeks before freeze. Gate to proceeding to Checkout (Step 16) is four-week soak with zero monetary reconciliation mismatches and zero order duplicates.
16. Extract Checkout: Distributed Saga Orchestration (Highest Risk) (depends on: 12, 13, 14, 15)
Highest-risk extraction, deliberately placed last among transactional work and only after components it orchestrates are individually proven at scale. This step composes independent services into coherent checkout flow.
**Checkout Orchestrator Service**: Build service that coordinates checkout: cart validation, price computation, inventory reservation, payment authorization, order creation. Design as explicit saga with named steps and compensating actions.
**Saga Orchestration**: Implement synchronous saga (single coordinator) or asynchronous (choreography via events), chosen based on latency testing (target checkout p99 < 5 seconds at peak). Synchronous preferred for checkout because customer waits; failure is visible. Steps:
1. Validate cart via Cart service
2. Compute price via Pricing service (cached if < 1 second old)
3. Reserve inventory via Inventory service
4. Authorize payment via Payment service
5. Create order via Orders service
**Compensating Transactions**: For every step, define compensation:
- Step 3 fails: Release inventory reservation
- Step 4 fails: Release inventory reservation, void authorization (if possible)
- Step 5 fails: Release reservation, void authorization, return payment to customer
- Step 2 recomputes and differs: Increase price, reject order; or decrease price, accept at old price (business rules decision, document explicitly)
**Idempotency End-to-End**: Checkout request includes idempotency key (unique per browser session + timestamp). Service deduplicates on this key. Retried checkout cannot double-charge or double-reserve; returns previous result.
**Timeout Handling**: Inventory reservation expires in 15 minutes (configurable). Payment authorization valid for 7 days (provider-specific). Order creation never times out; if hanging, manually investigate. Saga must fail safe to retryable state, never to half-committed order.
**Shadow Traffic Before Live**: Mirror live checkout traffic (100% of checkout requests during business hours) to new orchestration for minimum 2 weeks before any live cutover. Compare full outcomes: order ID, order total, inventory reservations, payment authorization IDs, error messages. Divergence > 0.001% blocks live cutover.
**Live Ramp During Open Window**: Ramp live traffic only during open delivery window (Feb–May or Aug–Nov). Gate and soak strictly: minimum four weeks before freeze. Keep monolith checkout path fully functional and warm (receiving live traffic via feature flag) as rollback target until Checkout service has survived one full peak.
**Peak-Readiness Gate Mandatory**: Hold six-week peak-readiness gate (Step 19) before proceeding to back-office migration (Step 18). Failed gate stops this work immediately and defers to next window.
17. Migrate Back-Office, Storefront, and Mobile Clients to Service APIs (depends on: 16)
Moves 300 back-office staff and client applications off monolith database direct access. Until this step, monolith database remains live dependency even where logic moved.
**Back-Office Screen Refactoring**: Migrate screens table by table. Replace direct SQL with service API calls through gateway. Start with orders (call Orders service), then customers (call Customer service), then inventory (call Inventory service). Build aggregation endpoints: /orders/{id}/full-details calls Orders + Payments + Inventory + Returns services, caches 30 seconds, returns unified response.
**Aggregation Endpoints and Caching**: Services are now call-chain away, not co-located. Back-office latency would suffer without caching. Implement short-lived cache (TTL 30 seconds) for frequently accessed data (customer profiles, recent orders). Graceful degradation: if one service slow, show cached data and alert staff.
**Storefront and Mobile App**: Both hit same endpoints (via gateway). Update storefront (server-rendered) to call service APIs while keeping old path functional behind feature flag; rendering regression becomes flag flip, not rollback. Mobile app points at gateway for migrated endpoints; keep old endpoints alive for un-updated app versions (users do not upgrade on schedule). Implement API versioning: v1 (legacy monolith), v2 (service APIs); clients request version in Accept header.
**API Versioning and Deprecation Windows**: Publish versioning rules: breaking changes trigger major version bump (v2 → v3). Old version supported for minimum 90 days after major release. Client teams must upgrade within window; do not force upgrade. Document deprecation timeline in API spec.
**Load Test Back-Office Concurrency**: Test 300 concurrent staff on top of peak storefront (480k orders/day). New services now carry both loads; autoscaling and database connection pools must handle burst. Simulate realistic staff queries: order searches, customer history, bulk refunds.
**Distributed Tracing for Debugging**: Every back-office request traced across services. Staff can view trace in UI; operations team can see which service was slow. Trace includes: request start, service calls, database queries, cache hits/misses.
**Monitoring and Runbooks**: Create runbooks for common issues: slow customer search (check Customer service load), payment lookup fails (check Payment service), order create fails (check Orders service latency). Link from dashboard to runbook.
**Gate to Monolith Decommissioning**: Back-office must be fully migrated (no direct SQL reads to monolith) before monolith core decommissioning (Step 18). This step completes organizational cutover.
18. Chaos Engineering, Resilience Testing, and Pre-Peak Validation (depends on: 17)
Validates new distributed architecture survives failure scenarios and peak load without cascading collapse. This step is as much about proving state is coherent as about finding failure modes.
**Chaos Game Days**: Scheduled monthly (or before each peak). Kill each service in turn (Search, Inventory, Orders, Payments, etc.); confirm storefront degrades gracefully (e.g., 'Search temporarily unavailable, catalog browsing still available') rather than failing completely. Kill database replicas; verify service continues with read-only or cached data. Kill message broker; verify no events lost and no reordering. Record each game day; publish findings and mitigation actions.
**Peak-Readiness Gate (Before Each Peak)**: Run six weeks before January and July peaks (mid-November, mid-May):
- **12x Load Test**: Generate realistic 480k orders/day traffic against production-shaped data (8 countries, 3 currencies, 4 languages, realistic product hierarchy). Measure checkout p99 < 5 seconds, search p95 < 1 second, payment < 2 seconds.
- **Capacity Headroom**: Confirm all services autoscale to handle 12x baseline. Database connection pools have headroom. Message broker partitions are sufficient. Cache hit rates do not collapse under load.
- **Rollback Rehearsal**: Execute full rollback of most recent service extraction in load-test environment. Measure rollback time; must be < 30 minutes including data reconciliation.
- **Error Budget Review**: Confirm SLO error budgets not burned significantly. If burned, identify culprit and mitigate before peak.
- **Evidence Publication**: Publish load-test results, capacity headroom metrics, rollback time, and SLO status. Gate is pass/fail; failed gate defers peak exposure and triggers root-cause work.
**Full System Load Test**: All services under load simultaneously. Measure inter-service latencies, database load, message broker throughput. Identify bottlenecks: pricing calculations, search queries, payment provider round-trip time, inventory reservations under concurrent access. Tune:
- Database query indexes
- Connection pool sizes
- Caching strategies
- Message broker partitions
- Service autoscaling thresholds
**Failure Mode Analysis**: Identify top 10 single-point-of-failure risks:
1. Payment provider outage → graceful degradation (pre-authorize smaller amounts?)
2. Inventory service down → checkout blocked; mitigation: cache inventory in checkout orchestrator
3. Pricing service down → checkout blocked; mitigation: cache last-known prices
4. Orders service down → checkout blocked; mitigation: queue orders in Kafka, replay when service recovers
5. Database down → all services blocked; mitigation: read-only replicas for queries
6. Message broker down → no events published; mitigation: outbox patterns ensure no event loss
7. API gateway down → all traffic blocked; mitigation: active-active gateway setup (two regions or multiple providers)
8. Warehouse sync delayed → inventory stale; mitigation: alert threshold, manual intervention process
9. Customer service down → login blocked; mitigation: cache tokens, allow anonymous checkout
10. Search service down → browsing blocked; mitigation: fallback to category list without search
For each failure, document mitigation (architectural change or operational procedure), test in chaos game day, and update runbooks.
**Synthetic Transaction Monitoring**: Implement real-world checkout, return, and search transactions executing every five minutes. Alert on failure before customers notice. Include multi-country, multi-currency variations.
**Performance Baseline Documentation**: Document baseline latencies (checkout, search, payment) at baseline load (40k orders/day). Load test must show no regression at peak; improvements accepted. Document these baselines in runbooks for operations team reference.
19. Monolith Decommissioning and Steady-State Operations (depends on: 18)
Safely retire monolith code once all services stable and production-proven. This step is final validation that new architecture is coherent; incomplete decommissioning signals hidden coupling.
**Module-by-Module Cleanup**: Delete extracted service code from monolith only after that service has survived one full peak (January or July, whichever comes first) or four clean weeks post-cutover, whichever is longer. Before deletion:
- Audit dead code: which stored procedures, views, tables, methods are no longer called
- Verify service API is the only interface for data owned by extracted module
- Confirm no service calls back into monolith code
- Delete extracted logic and dependencies
**Database Decommissioning**: Dropped tables are archived (not deleted) for 90 days (regulatory retention and emergency queries). After 90 days, drop and archive to long-term storage. Monolith database shrinks as modules extracted. When monolith becomes shell (mostly unused), decide: keep as fallback or shut down entirely.
**Cross-Module Stored Procedures**: All stored procedures touching multiple modules' tables must be eliminated before monolith shutdown. If any remain, move logic into services or refactor. Document any that cannot be moved; escalate as risk.
**Backup and Recovery Procedures**: Shift from single monolith snapshot to per-service snapshots. Each service team owns backup/recovery for their database. Document recovery procedures: which services recover in which order, which can tolerate data loss vs. which require point-in-time recovery. Test recovery monthly.
**Architectural Decision Records**: Publish final ADRs documenting:
- Why services were split at these boundaries
- What problems each split solved
- What trade-offs were made
- What cross-service communication patterns emerged
- What monitoring and alerting proved most useful
**Operational Runbooks**: Finalize runbooks for each team:
- Incident response: common failure modes, resolution steps, escalation paths
- Deployment procedures: how to deploy service, rollback procedure, expected latency
- On-call procedures: alert thresholds, page-worthy events, war room communication
- Database procedures: backup, restore, schema migrations, connection pool tuning
**Service Ownership Model**: Confirm each of five teams owns one or more services end-to-end:
- Codebase and CI/CD pipeline
- Database schema and migrations
- On-call rotation and SLOs
- Production incidents
- Capacity planning and scaling
No shared ownership; clear escalation paths between teams.
**Team Ramp-Down of Migration Work**: Migration enablement squad (formed in Step 1) transitions into steady-state platform team. Reduce migration velocity; redirect capacity to feature work on services.
**Exit Criteria and Project Close**:
- All rungs 1–6 of scope ladder complete (or deliberately stopped at rung boundary)
- Both peak seasons (January and July) survived without migration-caused incidents
- All services deployed independently by month 12
- Monolith reduced to < 5% of original codebase or decommissioned entirely
- All architectural decisions documented and team alignment confirmed
**Celebrate and Document Lessons**: Publish retrospective capturing:
- What went well: which techniques proved most valuable (golden master? chaos testing? soak periods?)
- What was hard: which services took longer, which risks materialized
- What would change next time
- Which rungs of scope ladder were reached and why work stopped where it did
**Deferred Work**: Explicitly list architectural or optimization work deferred to follow-up programs (e.g., Pricing DSL refactoring, read-write split at database level, multi-region deployment).
20. Peak Season Validation and Post-Peak Stabilization (depends on: 18, 19)
Proves new architecture survives peak and validates migration is truly complete. January and July peaks are the final test; this step verifies readiness and documents learnings.
**Pre-Peak Confirmation**: One week before peak start (Dec 25 for January peak, June 25 for July peak), confirm:
- All peak-readiness gate checks passed
- All services healthy and responding normally
- Database connection pools at capacity
- Cache hit rates normal
- Message broker lag within SLOs
- On-call rotations staffed
- War room communication channels open
**Peak Monitoring**: During peak (480k orders/day sustained for 2–3 weeks), maintain heightened monitoring:
- Every service dashboard visible in central war room
- Latency p99, p95, p50 trending in real time
- Error rate per service alarmed
- Database query performance monitored
- Message broker lag tracked
- Payment success rate watched (fraud filters, authorizations)
- Inventory reservation accuracy validated hourly
**Incident Response**: Any incident < 5 min MTTR automatically escalates to war room. Team lead validates:
- Root cause (service slow? database? payment provider?)
- Impact (customer-visible? checkout blocked? data corruption?)
- Mitigation (rollback flag? scale service? throttle traffic?)
- Recovery (how long to resolve?)
**Post-Peak Retrospectives**: Within one week of peak completion, each service team retrospectives on:
- Peak traffic patterns observed vs. load-test simulations
- Any incidents: root cause, time-to-detect, time-to-recover
- Performance variations: which services scaled, which became bottlenecks
- Data accuracy: any reconciliation mismatches discovered during peak
- Lessons for next peak
**Capacity Planning**: After peak, analyze:
- Database query times at peak: any unexpected slowdowns?
- Service autoscaling: did services scale early enough? were there cascading failures?
- Cache effectiveness: hit rates at peak vs. baseline
- Message broker: any message loss or reordering?
- Payment provider latency: did provider response times increase during peak?
**Final Validation**: Confirm scope ladder rung achieved:
- Rung 6 complete: back-office migrated, monolith core reduced, checkout orchestration stable
- Teams deployed independently during peak (or blocked from deploying due to freeze, which is correct)
- Zero unplanned downtime caused by migration
- All rollback procedures worked in chaos testing; never needed in production
**Program Closure**: Publish final evidence:
- Peak season metrics (order volume, success rate, latency, errors)
- Service-by-service stability (uptime, incidents, MTTR)
- Scope ladder rung reached
- Explicit deferred work list
- Team feedback and lessons learned
**Next Program Planning**: If rung 7+ desired (e.g., Pricing rules DSL refactoring, multi-region deployment), plan as separate 6-month program. Document in writing; do not creep scope into current program.
--- PROPOSAL 2 ---
Proposal ID: 2a819ee6-3a8b-48c8-a67f-7bcb82c07659
Content:
Estimated Complexity: high
Success Metrics: - Independent deployability: at least 4 of the 5 teams release their own artefact without coordinating with another team by month 5, and all 5 by month 9.
- The 30-minute maintenance window is retired by month 6; no release after that date requires a planned outage.
- Deployment lead time from merge to production is 30 minutes or less for a service, and each team releases at least 3 times per week by month 6.
- Zero unplanned downtime attributable to the migration across the 12 months; availability of 99.95% or better inside each peak window.
- Both January and July peaks pass with no migration-caused incident: 12x baseline load sustained, checkout p99 under 5 seconds, error rate under 0.5%, no queue backlog beyond 5 minutes.
- 100% of migration increments that reach production have a rollback demonstrated in a game day and executable in under 30 minutes.
- The rollback controller reverts a canary automatically on error-rate or latency divergence, proven in at least two live rehearsals per open window.
- Hourly reconciliation shows under 0.001% discrepancy on row counts and checksums per module; zero unexplained business-invariant violations; a monetary mismatch triggers automatic rollback.
- Cross-module joins and cross-module writes originating in application code are zero for every module at the moment it is extracted, enforced by database roles and CI rather than by review.
- Stored procedures touching more than one module's tables: zero for every extracted module.
- Pricing parity: 100% agreement with the golden master on a corpus of at least 1,000,000 historical requests across all 8 countries, 3 currencies and 4 languages, both before and after cutover.
- Search freshness improves from a nightly rebuild to under 30 seconds between a product change and its visibility in search results.
- Warehouse inventory freshness improves from 15 minutes to under 2 minutes end to end.
- Customer auth: zero forced logouts during cutover for both storefront and mobile clients, and no version of the mobile app in the field breaks at any point in the program.
- The checkout transaction remains inside the monolith through both peaks; the saga deferral is documented, accepted and signed off before month 12.
- The peak-readiness gate is passed with published evidence six weeks before both peaks, covering 100% of its defined checks.
- Scope ladder rungs 1–8 are complete within 12 months, or the program stops at a rung boundary in a documented, coherent, peak-safe state.
Steps (18):
1. Calendar-first charter, scope ladder and peak-readiness protocol
The binding constraint in this objective is the commercial calendar, not the technology, so the calendar is decided before anything else. Everything later obeys it.
- Declare the hard freezes against the real sales calendar, in the shape 1 December – 15 January and 1 June – 15 July. Inside a freeze only rollback-enabling and hardening changes ship.
- Reserve four 'risky cut' slots per year, roughly March–April and September–October. February, May, August and November are soak and hardening months and carry no new cutover.
- Forbid any cutover step from starting within six weeks of a freeze. Every cutover must end in a freeze-ready state: both paths live, flags reversible, reconciliation green.
- Publish the scope ladder. Rungs 1–8 are the core objective; rungs 9+ are optional. Slippage stops at a rung boundary in a coherent, peak-safe state, never mid-increment.
- Write the rollback charter: expand/contract schema change, feature-flag kill switch and a game-day rehearsal recorded before go-live.
- Write the abort criteria: the conditions under which the program stops, and who signs off.
- Create a migration enablement squad of six engineers on rotation from the five teams. It owns the platform, the shared cuts and the risky shared data work.
- Budget 40–50% of the five teams' capacity for migration and staff the ladder to that budget rather than filling the year.
2. Executable architecture map, table ownership and boundary enforcement (depends on: 1)
Five teams committing to one repository will silently re-couple anything that is separated and not policed, so enforcement is part of the map, not a later step.
- Run distributed tracing on the monolith for four weeks before drawing any boundary. Real call paths beat static imports for finding true coupling.
- Build a table-to-module and query-to-module map by parsing every SQL statement, ORM mapping and stored procedure, cross-checked against the database's own query logs.
- Assign each of the 350 tables to exactly one owning module. Tables nobody can own are declared contested and scheduled into S7.
- Score each candidate service on coupling, transactional risk, change frequency and peak-path criticality. This ranking drives the extraction order, not intuition.
- Add ArchUnit rules that fail the build on new cross-module Java dependencies, and a SQL linter that fails on cross-module joins and writes. Existing violations are frozen into a baseline file that may only shrink.
- Publish the target service list, the owning team per service and the reasoning as ADRs.
- Re-rank the scope ladder at the month-six review using what the map actually showed.
3. Delivery platform: per-module pipelines, gateway, feature flags, environments (depends on: 1, 2)
No module is extracted until its team can deploy, flag and route on its own.
- Kubernetes namespaces, quotas and autoscaling policies sized for 12x peaks.
- API gateway in front of the monolith from day one as the strangler entry point. Storefront, mobile and back-office traffic all flow through it even while it routes everything to the monolith.
- One CI/CD pipeline and one environment per module. The monolith keeps its pipeline for hotfixes until S5 replaces it.
- A feature-flag service, with every new call path flag-guarded. Flags are the primary rollback instrument for the whole program.
- Golden-path templates for a new service: build, pipeline, observability, health checks, flag integration, database migration tool.
- Two permanent environments: a production-shaped soak environment and a load-test environment able to generate 12x traffic.
- Secrets management and per-environment configuration so behaviour changes never require a monolith redeploy.
4. Observability, business SLOs and the automated rollback controller (depends on: 3)
A canary is only trustworthy if it is judged automatically, so the rollback promise is built once here and reused by every later step.
- Centralised logging, metrics and distributed tracing, with trace correlation across gateway, monolith and every service.
- Instrument the monolith's blind spots: query latency by module, connection-pool saturation, Lucene rebuild duration, warehouse file-exchange lag.
- Define SLOs on business outcomes: checkout success rate, order confirmation p99, search latency, payment authorisation rate, price computation latency, warehouse sync freshness.
- Attach an error budget to each SLO. When a service burns budget, its rollout stops and its flags revert automatically. No negotiation during a peak.
- Build the rollback controller: on error-rate or latency divergence during a canary, the gateway shifts traffic back and disables flags without human action.
- Per-service dashboards a tired engineer can read at 03:00, plus one program dashboard showing progress against the scope ladder.
5. Split the deployment unit and retire the 30-minute maintenance window (depends on: 2, 3)
This is the cheapest large win in the program and it delivers the headline objective — independent deployability — before any process separation, by splitting the build and the release train while the code still runs together.
- Split the single artefact into one build per owning module with a shared parent.
- Allow modules to be released as separate artefacts on the existing runtime first. Independent deployability is a build and release property long before it is a topology property.
- Retire the two-week coordinated release train. Each team gets its own pipeline, cadence and on-call rota, with the gateway and schema compatibility as the contract between teams.
- Adopt expand/contract database migrations so schema and code changes no longer have to ship together.
- Replace the maintenance window with blue-green deployment on two identical stacks, traffic switched at the gateway and rollback performed by switching back.
- Publish the measurement: deployment lead time, deployment frequency per team, and the share of releases that needed no coordination with another team.
6. Seam-level verification: golden master, contracts, shadow diffing and reconciliation (depends on: 2, 3)
A two-million-line monolith cannot reach blanket coverage in a year. Verification is aimed exactly where the cut will be made, which is where it is affordable and where it actually pays.
- Build a characterization harness that records real production requests and responses, anonymised, as a golden master. This is the safety net for every extraction.
- Require every extracted service to pass the golden master on its public API before it takes live traffic, producing a diff report rather than a pass/fail.
- Consumer-driven contract tests between the monolith and each new service, and between services, so a breaking change breaks a build rather than production.
- Shadow traffic mirroring live requests to the new service with field-by-field comparison. The traffic ramp is gated on the divergence rate.
- Per-module data reconciliation as a first-class test: row counts, checksums and business invariants on a schedule, with an owner and an alert threshold.
- Synthetic canary transactions that run a real checkout, return and search every few minutes and alert on functional regression before customers notice.
- Track line coverage only for newly written service code, where the target is 80%. Blanket coverage of the monolith is explicitly not a goal.
7. Data platform: schema ownership, join elimination, CDC, outbox and the four-stage cutover playbook (depends on: 2, 3, 6)
The hardest part of the program, and the part that does not depend on service extraction, so it starts in month one and runs in parallel with everything else.
- Enforce ownership inside the database: one PostgreSQL role per module, able to write only its own schema and read others only through defined views. Cross-schema writes are rejected by the database, not by convention.
- Inventory every stored procedure, attribute it to one module, and either move it into that module's code or leave it as a module-private function. After a module is extracted, no stored procedure may touch two modules' tables.
- Eliminate cross-module joins one at a time, replacing each with an API call, an event-fed read model or a duplicated read-only projection. Track the count per module and drive it to zero before that module is cut.
- Stand up change data capture with Debezium reading the PostgreSQL WAL into Kafka. This publishes monolith domain events with no application change, the lowest-risk start available.
- Add a transactional outbox for new services so their events and their state changes commit together.
- Adopt one reusable four-stage cutover playbook and apply it identically every time. Stage A: the service owns its schema logically, reads from CDC into its own store and serves shadow traffic only. Stage B: reads cut over, the monolith stays system of record. Stage C: writes cut over and the monolith's tables become read-only replicas fed by reverse CDC. Stage D: old tables and dead code are dropped only after a full peak or four clean weeks, whichever is longer.
- Make stage C genuinely reversible: because the sync direction can be flipped, rolling back a write cutover is a configuration change plus a reconciliation pass, not a data restore.
- Build the reconciliation service once, here, so every later cutover has an objective consistency check with thresholds and owners.
- Deliberately defer the 1.2 TB physical split. Services start on the existing cluster in their own schemas; physical separation is post-program work.
8. Rung 1 — Extract Catalogue and Search (depends on: 5, 6, 7)
The first extraction: read-heavy, mostly isolated, no transactional risk. It also pays for itself, because replacing the nightly Lucene rebuild with real-time indexing is a visible business win that buys political cover for the harder cuts.
- Create a Catalog service owning product, category and media tables plus its own search index.
- Feed it from CDC so product and price changes appear in search within seconds instead of after a nightly rebuild.
- Route through the gateway behind a flag and ramp 1% → 5% → 25% → 50% → 100%, with the rollback controller able to revert to the monolith's internal Lucene path at any point.
- Run shadow traffic and compare result sets before any live traffic, then keep the old index warm for two weeks after full cutover.
- Include the mobile app in the same ramp, since it hits the same endpoints.
- Land this cut in a risky-cut slot and let it soak at least four weeks before the freeze.
9. Rung 2 — Extract Returns, the first write path (depends on: 5, 6, 7)
Second extraction and the first that owns writes and a database. Returns is chosen because it is off the peak-critical path, has modest coupling, and exercises the full four-stage playbook at low stakes.
- Build the Returns service with its own schema, consuming order and customer events rather than joining their tables.
- Run the playbook end to end: shadow reads, read cutover, then write cutover with reverse CDC keeping the monolith's tables current.
- Prove the rollback path in a game day before write cutover, including a reconciliation pass and a re-run of the golden master.
- Keep the back-office returns screens on the monolith for now, so staff workflow is untouched by this step.
- Record every friction point and correct the playbook. The real output of this step is a proven, reusable procedure, not just one service.
10. Rung 3 — Extract Inventory and retire the 15-minute warehouse file exchange (depends on: 5, 6, 7)
Removes one of the sharpest coupling points in the system and unblocks the checkout work. Inventory couples the monolith to an external warehouse process rather than to other modules, so it can run in parallel with the other early cuts.
- Build the Inventory service to ingest the warehouse feed directly and publish stock-level events.
- Preserve the existing file-based interface for the first weeks, running the new ingest in parallel with the legacy feed and reconciling hourly until they agree.
- Keep the monolith's inventory tables as an event-fed projection, so cart and checkout keep working unchanged during the cut.
- Design reservation semantics now — reserve, confirm, release, with expiry — even though checkout is not yet extracted. The API is needed later and is cheap to get right here.
- Load-test inventory ingest at 12x, because the warehouse feed schedule and the sales peaks do not always coincide.
- Cut over reads first, then writes, with the rollback controller able to restore the file feed as the source of truth.
11. Rung 4 — Extract Customer Accounts and Loyalty with a conservative auth strategy (depends on: 5, 6, 7, 9)
Customer accounts and loyalty, including the authentication decision. Auth is the step that most often derails e-commerce migrations, so the auth path is deliberately moved last and guarded hardest.
- Build the Customer service owning profile, address and loyalty tables, with country-specific loyalty rules expressed as data where possible and as code where not.
- Keep authentication in the monolith for the first phase. Move token issuance only once customer data is stable, and never within four weeks of a freeze.
- Introduce distributed session handling and a token-validation API so services can verify identity without querying the monolith database.
- Cut over reads, then writes, with reverse CDC, validating against the golden master across all 8 countries and 4 languages.
- Verify the mobile app's session behaviour explicitly, since it holds long-lived sessions the storefront does not.
- Move loyalty point accrual and redemption last, because a loyalty error is a customer-visible financial error, not a technical incident.
12. Rung 5 — Extract Cart (depends on: 8, 10, 11)
The cart is stateful and sits directly in front of checkout. It is done before pricing because the checkout path needs a stable cart boundary to call.
- Build the Cart service on Redis for session and line-item state, validating products and inventory through service calls rather than database joins.
- Make every cart operation idempotent, because a retried add or remove during a peak must not duplicate a line item.
- Keep the cart tables in the monolith as a read-only projection fed by events, for rollback and for the not-yet-migrated back-office screens.
- Ramp traffic while monitoring cart abandonment rate as the business metric, since cart latency shows up as lost revenue rather than as errors.
- Exercise anonymous and authenticated carts separately; they follow different paths and fail in different ways.
- Land this cut in a risky-cut slot with a full four-week soak before the freeze.
13. Rung 6 — Extract Pricing and Promotions as an unchanged black box (depends on: 5, 6, 7)
Extracts the 200,000-line pricing module without rewriting it. The rules are not understood by anyone, so they are wrapped and characterized rather than reverse-engineered. Rule decomposition, documentation and a DSL are explicitly out of scope for these twelve months.
- Build a golden master corpus from at least a million real historical pricing requests and their recorded outputs, covering all 8 countries, 3 currencies, 4 languages, plus every promotion type that can be discovered.
- Invert the module's dependencies rather than its logic: pricing obtains customer, product and inventory data from event-fed read models it owns, not from synchronous fan-out to three services. A fan-out on the price path is the wrong shape at 12x peak.
- Move the pricing code into its own service unchanged, owning its tables after cutover, and expose a single decision API.
- Run it in shadow mode for at least four weeks against live traffic, comparing every computed price with the monolith. Any divergence blocks the ramp.
- Cut over behind a flag with per-country ramps, since a pricing error is a financial and legal exposure in each jurisdiction rather than a technical incident.
- Keep the in-monolith evaluator available and warm as the rollback path for at least one full peak after cutover.
- State in writing that rule decomposition is deferred to a follow-up program, so it does not creep back into this one.
14. Rung 7 — Extract Payment under a stricter regime than anything else (depends on: 5, 6, 7)
Payment mistakes are irreversible and regulatory, so this module gets the strictest controls in the program.
- Build the Payment service owning the integration with the three providers: tokenisation, authorisation, capture, refund and provider webhooks.
- Reduce PCI scope rather than expand it. No raw card data at rest in the new service, credentials in secrets management, no card data in logs or traces.
- Make every payment operation idempotent with explicit idempotency keys, because retries at peak are normal and double charges are not recoverable.
- Cut over provider by provider rather than all three at once, starting with the lowest-volume provider.
- Run the golden master across all decline, timeout, partial-authorisation and refund scenarios, and rehearse the fallback to the monolith's direct provider integration.
- Verify fraud detection and 3-D Secure paths explicitly, since they are usually the least covered and the most visible when they break.
- Land this cut early in a risky-cut slot so it soaks well before the freeze.
15. Rung 8 — Extract Order Management with an explicit state machine (depends on: 9, 10, 13, 14)
Order management becomes the record of truth for the order lifecycle, after the services it depends on exist and are stable.
- Build the Order service with its own database and an explicit order state machine that validates every transition.
- Introduce event sourcing for order status so the audit trail satisfies regulators and fulfilment teams, and so state can be rebuilt after an incident.
- Consume events from payment, inventory and returns rather than polling or joining.
- Cut over reads first for the five teams that query orders, then writes, keeping the monolith's order tables as a reverse-CDC projection.
- Reconcile order counts and monetary totals hourly against the monolith throughout the transition. A monetary mismatch is an immediate rollback, not a ticket.
- Load-test concurrent order state transitions at peak, since the state machine becomes the new serialisation point.
16. Keep the checkout transaction in the monolith for the first peak, and decide on the saga afterwards (depends on: 12, 13, 14, 15)
This is the deliberate difference from the obvious plan. Checkout is the single highest-risk cut and it sits directly on the peak-critical path. A distributed saga across pricing, inventory, payment and orders buys elegance at the cost of the two things the brief protects most: January and July sales.
- Thin the monolith's checkout into a synchronous orchestrator that calls the Pricing, Inventory, Payment and Order services through the gateway.
- Implement compensation inline in the orchestrator — a failed authorisation releases the reservation, a failed order creation voids the authorisation — without introducing a general saga framework.
- Propagate idempotency keys end to end so a retried checkout cannot double-charge or double-reserve.
- Handle the peak case explicitly: when inventory or pricing is slow, checkout must fail to a retryable state, never to a half-committed order.
- Require the peak-readiness gate before the cut that makes checkout depend on remote calls. A failed gate is a stop, not a delay; the monolith stays authoritative.
- Review after a full peak whether the orchestrator is worth extracting as a saga-based Checkout service. That decision belongs to the follow-up program, with peak data in hand.
- Document and sign off the deferral, so it is an accepted design choice rather than an unfinished step.
17. Migrate the back-office, storefront and mobile clients off the monolith database (depends on: 16)
Until the clients move, the monolith's database stays a dependency even where the logic has already left.
- Refactor back-office screens to consume service APIs through the gateway, replacing direct SQL access table by table, starting with orders and customers.
- Add aggregation endpoints where a screen needs several services, plus a short-lived cache so 300 staff do not multiply load on the new services.
- Update the server-rendered storefront to call service APIs while keeping the existing rendering path working behind a flag, so a rendering regression is a flag flip rather than a rollback.
- Point the mobile app at the gateway for migrated endpoints and keep the old endpoints alive for un-updated app versions. No version of the app in the field may break at any point in the program.
- Publish API versioning rules and deprecation windows so teams can change their services without coordinating with client releases.
- Load-test the back-office with 300 concurrent staff on top of peak storefront traffic, since the two now share services.
18. Decommission the extracted modules, validate the second peak, write the exit report (depends on: 17)
Removes what is left and proves the new architecture survives a peak. This step is as much about proving the state is coherent as about deleting code.
- Delete dead code and dropped tables module by module, only after a module has run a full peak or four clean weeks, whichever is longer.
- Keep read-only access to the old database for a defined period for historical and regulatory queries, then archive and decommission it.
- Replace the monolith's remaining cross-module reads with service calls or event-fed projections. The monolith should now be a small set of modules plus the checkout orchestrator.
- Re-run the full 12x load test against the new topology across all 8 countries, 3 currencies and 4 languages, and tune autoscaling, connection pools and broker partitions from the results.
- Run chaos game days: kill each service in turn and confirm the storefront degrades gracefully rather than failing completely.
- Confirm and publish the peak-readiness gate evidence before the second peak. A failed gate defers remaining work rather than risking the peak.
- Write the exit report: final service boundaries, data ownership, runbooks, SLO history, the scope-ladder rung actually reached, and the list of work explicitly deferred to a follow-up program.
--- PROPOSAL 3 ---
Proposal ID: 8a14de17-3842-4134-ba82-c6e281ddebf1
Content:
Estimated Complexity: high
Success Metrics: 1. Zero unplanned downtime during the 12-month migration and subsequent peaks.
2. Peak season (Jan/Jul) capacity maintained at 12x baseline with no performance degradation in checkout flows.
3. 100% of Pricing and Promotion transactions match the Golden Master characterization tests post-extraction.
4. Five teams deploying independently at least once per week without coordination conflicts.
5. All monolith-to-service data synchronization latency under 2 seconds (near real-time).
6. Database size reduced by >40% through extraction and cleanup of legacy unused tables.
7. Search index refresh time reduced from 24 hours (nightly) to < 1 minute (real-time).
Steps (16):
1. Program Governance, Peak Calendar, and Scope Ladder
Establish the binding constraints of the program before any technical work begins. The calendar dictates that the January and July sales peaks are immovable objects; therefore, all migration steps must be scheduled around them.
2. Platform Foundation: Kubernetes, Gateway, and Observability (depends on: 1)
Deploy the infrastructure layer required to run services independently and observe traffic flow. This includes a Kubernetes cluster for workloads, an API Gateway as the central routing control point, and a full observability stack (Tracing, Metrics, Logs). The Gateway is the primary mechanism for rollback via traffic shifting.
3. Data Foundation: CDC, Outbox Pattern, and Transactional Events (depends on: 1, 2)
Implement Change Data Capture (Debezium) and a Transactional Outbox pattern in the monolith. This creates the event backbone required for eventual consistency and allows new services to subscribe to monolith changes without touching the legacy code logic. This step runs in parallel with platform setup.
4. Architectural Decoupling: Table Ownership and Anti-Corruption Layer (depends on: 2)
Define strict ownership for the 350 tables and implement an Anti-Corruption Layer (ACL) to intercept cross-module dependencies. This involves creating separate database schemas or logical boundaries for high-coupling areas like Orders and Catalogue to prepare for physical separation.
5. Characterization Test Harness: The Golden Master (depends on: 2, 3)
Build a replay engine and capture a 'Golden Master' corpus of production traffic. This automated test suite records request/response pairs from the monolith, creating a baseline for validation. This is critical for the Pricing module and high-traffic endpoints where refactoring is impossible.
6. First Extraction Pilot: Catalogue and Search (Read-Heavy) (depends on: 3, 4, 5)
Extract the Catalogue and Search services. These are low-risk (read-heavy) and validate the strangler fig pattern. Implement real-time search indexing via CDC events, replacing the nightly Lucene rebuild. Use the Golden Master to verify product data and search results match the monolith.
7. Second Extraction: Inventory Synchronization (depends on: 3, 5)
Extract Inventory management, specifically handling the integration with the external warehouse system (15-minute sync). This removes a critical dependency from the monolith and enables real-time stock visibility. The service acts as the single source of truth for stock levels.
8. Third Extraction: Customer Profile and Identity (depends on: 3, 4)
Extract Customer Accounts and Profile management. Move authentication logic and customer data ownership to a dedicated service. Ensure the Mobile App and Storefront can authenticate against the new service while maintaining session compatibility via JWT or shared session state.
9. Pricing Module Stabilization: Black Box Extraction (depends on: 5)
Extract the 200,000 LOC Pricing and Promotions module as a 'Black Box' service. Do not refactor the logic; wrap it. Use the Golden Master to validate 100% accuracy across all 8 countries and complex promotion rules. This step is strictly scheduled outside of any peak season.
10. Core Transactional Extraction: Orders and Order Management (depends on: 6, 7, 8, 9)
Extract the Order Management domain, including order creation, state machines, and lifecycle tracking. This service acts as the consumer of events from Inventory, Pricing, and Customer services. It replaces the monolith's direct order processing logic.
11. Checkout Orchestration and Saga Implementation (depends on: 7, 9, 10)
Implement the Checkout Service, acting as the orchestrator (Saga) for the payment process. It coordinates the distributed transaction across Cart, Pricing, Inventory, and Payments. It handles compensating transactions (e.g., releasing inventory on payment failure) to ensure data consistency.
12. Payment Provider Integration Service (depends on: 10, 11)
Extract the logic responsible for connecting to the three payment providers. This service handles authorization, capture, and refunds. By isolating this, the monolith no longer holds sensitive payment processing logic, reducing PCI scope and coupling.
13. Return and Refund Workflow Extraction (depends on: 10, 12)
Extract the Returns and Refunds logic. This service consumes order events to trigger return workflows, updates inventory, and requests refunds from the Payment Service. This completes the reverse logistics capability as a microservice.
14. Legacy Monolith Decommissioning: Strangler Finish (depends on: 10, 11, 12, 13)
Remove the extracted logic from the monolith. The monolith is now a legacy shell containing only the storefront rendering layer (which delegates to APIs) and potentially the Back-Office (if not yet migrated). This step involves rigorous cleanup of unused code and database tables.
15. Back-Office Migration and Staff Tooling (depends on: 14)
Migrate the Back-Office (300 staff users) to use the new service APIs. This may involve a dedicated BFF (Backend for Frontend) service that aggregates data from Orders, Customers, and Inventory for the staff UI, replacing direct database joins in the monolith.
16. Operational Handover and Autonomous Team Setup (depends on: 15)
Finalize team ownership. Each of the five teams is assigned to specific services (e.g., Team A owns Inventory and Search, Team B owns Orders and Checkout). Transfer on-call rotations and disaster recovery runbooks to the new services.
Instructions:
1. Carefully evaluate each proposal considering:
- Clarity and detail of the proposed steps.
- Overall alignment with the Main Objective.
- Quality and relevance of the proposed success metrics.
- Coherence of dependencies between steps (if any).
2. Think deeply about each proposal, analyzing its strengths and weaknesses. Consider how well each proposal addresses the main objective and which one would be most effective.
After your thorough analysis, give the Proposal ID of the selected proposal and a one- or two-sentence justification of your choice.
{"selected_proposal_id": "2a819ee6-3a8b-48c8-a67f-7bcb82c07659", "justification": "Proposal 2 is superior because it correctly identifies that a full distributed checkout extraction cannot realistically survive the January and July peak seasons within a 12-month window. By deliberately keeping the checkout transaction inside the monolith as a synchronous orchestrator for the first year, it perfectly aligns with the non-negotiable requirement to preserve peak capacity and avoid unplanned downtime during sales, whereas Proposal 1's timeline is dangerously optimistic and Proposal 3 lacks the necessary architectural detail and risk mitigation strategies."} |
Selected plan
1. Program Setup, Scope Ladder, Organizational Model, and Peak-Safe Calendar
Establishes the governance framework and constraints that all later work obeys. The calendar is the binding constraint—January and July peaks must not be put at risk—so it is decided first, before any technical choices.
Inception and Baselines: Run a two-week inception to establish current state: build time, deployment lead time, change failure rate, MTTR per team, module-change frequency, database load profiles (all measurable, not asserted).
Calendar and Freeze Windows: Declare hard freezes from December 1–January 15 and June 1–July 15; only rollback-enabling and hardening changes allowed during freezes. Confirm two open delivery windows per year (February–May and August–November); all migration work must fit these windows. No change on checkout path lands within four weeks of a freeze.
Scope Ladder: Define ranked rungs 1–6 that deliver the core objective; rungs 7+ are optional. Slippage means stopping at a rung boundary, never mid-increment. Rungs: 1. Platform ready. 2. Search extracted and proven. 3. Returns and Inventory proven at low stakes. 4. Payment and Orders stable. 5. Checkout orchestration live and soaking. 6. Back-office migrated, monolith core reduced.
Organizational Model: Define service-aligned teams (Search, Orders, Inventory, Payments, Customer, Fulfillment) with clear ownership, on-call rotations, and SLOs per service. Each team owns codebase, pipeline, database schema, and incidents by month 6. Transition plan: teams split duties (monolith maintenance + service) until month 3, then shift to service-primary by month 6.
Rollback Charter: Every increment ships an expand/contract database change, a feature-flag kill switch, and a recorded game-day rehearsal. No go-live without tested rollback in < 30 minutes.
Peak-Readiness Gate: Define gate to run six weeks before each peak (mid-November, mid-May): 12x load test, capacity headroom check, rollback rehearsal, error-budget review. Gate is pass/fail; failed gate defers work to next window.
Capacity Budget: Allocate 40–50% of five teams' capacity for migration; staff scope ladder to fit capacity, not to fill the year. Create migration enablement squad of six rotating engineers to own platform, shared cuts, and risky data work.
2. Executable Architecture Map, Table Ownership, and Boundary Enforcement (after 1) from P2 · round 1 step 2
Produces an architecture map that the build itself enforces. Five teams in one repo will silently re-couple anything separated if not policed, so enforcement is embedded in the map.
Real Coupling via Tracing: Instrument monolith with distributed tracing; let it run four weeks to capture real call paths—static imports miss true coupling.
Table Ownership Matrix: Parse every SQL statement, ORM mapping, and stored procedure; cross-check against database query logs. Build table-to-module and query-to-module map. Assign every 350 table to exactly one owning module; tables nobody can own are 'contested' and scheduled into data work (Step 7).
Scoring and Extraction Sequence: Score each candidate service on coupling, transactional risk, change frequency, and peak-path criticality. This ranking (not intuition) drives extraction order.
Enforcement via Automation: Add ArchUnit rules to CI to fail builds on new cross-module Java dependencies (existing violations frozen in baseline that may only shrink). Add SQL linter to CI to fail on cross-module joins and cross-module writes (same shrinking baseline). Violations tracked weekly in architecture review.
Stored Procedure Audit: Inventory all stored procedures; attribute to owning module; plan move into module code or leave as module-private function. No stored procedure may touch two modules' tables post-extraction.
Architecture Decision Records: Publish target service list, owning team per service, and reasoning as ADRs.
Mid-Program Review: Hold review at month 6 to re-rank scope ladder using what the map actually revealed. This is the one planned re-planning point of the program.
3. Delivery Platform: Per-Service Pipelines, Gateway, Feature Flags, and Environments (after 1, 2) from P2 · round 1 step 3
Builds the delivery and traffic machinery that makes every later step reversible. No service is extracted until its team can deploy, flag, and route independently.
Kubernetes and Namespaces: Extend platform on Kubernetes (or existing container platform) with one namespace per service, quotas, and autoscaling sized for 12x peak (480k orders/day). Establish dev/staging/prod with strict resource isolation.
API Gateway: Deploy API gateway (Kong, AWS ALB) in front of monolith as strangler entry point. Storefront, mobile app, and back-office traffic flow through gateway from day one, even while routing everything to monolith. Gateway enforces rate limiting, bulkheads, timeouts, and circuit breakers.
Feature-Flag Service: Deploy centralized feature-flag system (LaunchDarkly, Unleash). Require every new call path to be flag-guarded. Flags are the primary rollback instrument; changes to traffic routing require no code deployment.
Per-Module CI/CD Pipeline: Give every module its own independent CI/CD pipeline and environment. Monolith keeps current pipeline for hotfixes until Step 5 replaces it. Pipeline includes automated security scanning, performance baselines, and contract-test gates.
Secrets and Configuration: Introduce secrets management (Vault) and per-environment configuration. Behavioral changes require no monolith redeploy.
Golden-Path Templates: Define reusable templates for new services: build layout, Dockerfile, pipeline stages, observability instrumentation, health checks, feature-flag integration, database migration tool. Extraction starts from template, not blank page.
Permanent Environments: Reserve two full-size environments: (1) production-like soak environment for multi-week stability validation, (2) load-test environment capable of 12x traffic generation against production-shaped data (8 countries, 3 currencies, 4 languages, realistic product catalog).
4. Observability, Business SLOs, Error Budgets, and Automated Rollback Controller (after 3) from P2 · round 1 step 4
Makes the system observable so canaries are judged automatically and reverted without human guessing. This is the prerequisite for rollback promises in all later steps.
Observability Foundation: Deploy centralized logging (ELK/Loki), metrics (Prometheus/Grafana), and distributed tracing (Jaeger) with trace correlation working across gateway, monolith, and every new service from day one.
Blind-Spot Instrumentation: Instrument monolith's unmeasured aspects: query latency by module, connection-pool saturation, Lucene rebuild duration, warehouse file-exchange lag, stored procedure execution time, lock contention.
Business SLOs: Define SLOs on business outcomes, not infrastructure:
- Checkout success rate ≥ 99.5%
- Order confirmation latency p99 ≤ 5 seconds at baseline (40k orders/day) and peak (480k orders/day)
- Search result latency p95 ≤ 1 second
- Payment authorization latency ≤ 2 seconds
- Price computation latency ≤ 200 ms
- Warehouse sync freshness ≤ 2 minutes end-to-end (vs. current 15 minutes)
- Cross-module data consistency: hourly reconciliation shows < 0.001% row-count discrepancy
Error Budget and Rollback Policy: Attach error budget to each SLO. When a service burns budget (or latency diverges > threshold during canary), its rollout stops automatically and flags revert without negotiation. Document policy explicitly; use during peaks without exception.
Automated Rollback Controller: Build system that monitors error rate and latency divergence during canary. On breach, gateway shifts traffic back and flags disable automatically. Fallback requires no human intervention. Test this automation in monthly game days.
Dashboards: Create per-service dashboards readable by tired engineers at 3 AM (traffic, errors, latency p50/p95/p99, database load). Create program dashboard showing progress against scope ladder, rung by rung.
5. Pricing Module: Rules Catalog and Golden-Master Characterization (Parallel with Data Platform) (after 1, 2)
Catalog the 200k LOC pricing engine behavior before any extraction attempt. This is the foundational risk mitigation for the most complex module; it runs in parallel with data platform work (Step 7) because it is independent of infrastructure.
Rules Discovery and Documentation: Analyze and document all pricing rules in scope: country-specific logic (8 countries), currency handling (3 currencies), promotional rules, seasonal pricing, bulk discounts, loyalty point applications, regional variations. Create a living rules inventory.
Historical Request Corpus: Capture at least 1 million real historical pricing requests from production logs, covering all 8 countries, 3 currencies, 4 languages, all promotion types discoverable, edge cases, peak-season variations. Record exact inputs and outputs.
Golden-Master Characterization Suite: Build automated harness to replay corpus against monolith, capturing deterministic responses. This suite is the 'golden master': any new pricing service must match 100% of outputs. Suite becomes the automated gate for pricing extraction (Step 14).
Test Data Expansion: Supplement historical data with synthetic edge cases: multi-currency conversions, minimum purchase thresholds, conflicting promotions, time-based seasonal rules, inventory-driven pricing, customer-segment overrides.
Dependency Mapping: Explicitly document which customer attributes, product attributes, inventory levels, time-based factors, and external parameters affect pricing. Identify all cross-module dependencies that pricing currently reads from monolith (e.g., customer loyalty status from Customer module, product hierarchy from Catalogue module).
Baseline Validation: Run golden master against monolith to establish baseline passing rate. Document any non-deterministic behavior or race conditions found. This baseline is locked; no drift allowed during migration.
CI Gate Definition: Define hard rule: pricing service extraction cannot proceed until characterization tests pass 100% against both monolith and new service. Any divergence blocks ramp. This gate is not negotiable.
6. Seam-Level Verification: Golden Master, Contracts, Shadow Diffing, and Reconciliation (after 2, 3) from P2 · round 1 step 6
Replaces impossible goal of blanket test coverage with verification exactly at the cut point. A 2M-line monolith cannot reach 70% coverage in a year; a service boundary can be verified to very high standard in weeks.
Characterization Harness for All Services: Build framework to record real production requests (anonymizing PII) and replay against monolith. Capture full responses as golden master. Every extracted service must pass golden master on its public API before taking live traffic. Output a diff report, not pass/fail.
Consumer-Driven Contracts (Pact): Require contracts between monolith and each new service, and between services themselves. A change on one side breaks a build instead of waiting for production. Contracts versioned; breaking changes trigger explicit communication plan.
Shadow Traffic and Response Diffing: Mirror live requests to new service; compare responses field by field (not just status codes). Measure divergence rate continuously. Gate traffic ramp on divergence < 0.01% for 48 hours.
Per-Module Data Reconciliation: Build data reconciliation as first-class test, not afterthought. Compare row counts, checksums, and business invariants on hourly schedule. Owner assigned; alert threshold set. Reconciliation runs continuously during transition period (Stages A–C of cutover playbook).
Synthetic Canary Transactions: Implement real checkout, return, and search transactions executing every few minutes. Alert on functional regression before customers notice. Include multi-country, multi-currency variations.
Explicit Non-Goal: Do not pursue blanket line coverage of monolith. Track coverage only for newly written service code, target 80%. Seam-level verification replaces this impossible goal.
7. Data Platform: Schema Ownership, Join Elimination, CDC, Transactional Outbox, and Four-Stage Cutover Playbook (after 2, 3) from P2 · round 1 step 7
The hardest and most under-specified part of most migrations. This work is independent of service extraction, so it starts in month 1 and runs in parallel. It is the foundation for reversible data transitions.
Database-Enforced Ownership: Assign every PostgreSQL table to exactly one module. Create one role per module, able to write only its own schema and to read others only through defined views. Database rejects cross-schema writes at the engine level, not by convention. Test this enforcement in CI.
Stored Procedure Refactoring: Inventory every stored procedure, attribute it to owning module. Either move logic into that module's application code or leave as module-private database function. After extraction, no stored procedure may touch two modules' tables.
Cross-Module Join Elimination: Eliminate cross-module joins one at a time, replacing each with an API call (preferred during cutover), an event-fed materialized read model, or a duplicated read-only projection. Track count per module; drive to zero before that module is extracted.
Change Data Capture (CDC): Deploy Debezium reading PostgreSQL WAL into Kafka. This publishes monolith domain events with zero application change—lowest-risk start possible. Configure per-table CDC; test at peak load (480k events/day during 12x peak).
Transactional Outbox Pattern: For all new services, add outbox table. When service writes business state, it writes domain event atomically in same transaction. Outbox relay publishes to Kafka, ensuring no event loss. Implement poison-pill handling for failed publishes.
Four-Stage Cutover Playbook (Reusable): Define one playbook applied identically every service extraction:
- Stage A (Shadow-Read): Service owns schema logically, reads from CDC into its own store, serves shadow traffic only. Monolith remains system of record; no cutover yet.
- Stage B (Read Cutover): Reads cut over to new service via flag. Monolith stays system of record via reverse-CDC replication. Rollback is flag flip + reconciliation pass.
- Stage C (Write Cutover): Writes cut over to new service. Monolith tables become read-only replicas fed by reverse CDC from service. Rollback is configuration change (flip sync direction) + reconciliation, not data restore.
- Stage D (Deletion): Old tables and dead code dropped only after module has survived one full peak (January or July) or four clean weeks, whichever is longer. Maintain 90-day read-only archive of old tables for regulatory retention and emergency queries.
Reconciliation Service: Build now (not later) so every cutover has objective consistency check. Compare row counts, business-invariant checksums, monetary totals hourly. Owner assigned; thresholds set. Mismatch is immediate rollback signal.
Storage Migration Timeline: New services start on existing cluster with own schemas. Physical database split (move to separate cluster) happens only once module is stable and proven at peak. This removes a critical-path blocker and allows parallelization.
8. Extract Catalogue and Search: Read-Heavy Pilot Service (after 5, 6, 7)
First extraction, chosen because it is read-heavy, isolated, and carries no transactional risk. It also pays for itself: replacing nightly Lucene rebuild with real-time indexing is a visible business win that buys political cover for harder cuts.
New Catalogue Service: Create service owning product, category, media, and attributes tables. Build search API using Elasticsearch/OpenSearch with real-time indexing.
CDC Feed: Subscribe to CDC stream from monolith. ProductUpdated, PriceChanged, InventoryUpdated events trigger real-time search index refresh. Product availability reflects in search within < 60 seconds of change (vs. nightly rebuild).
Shadow Traffic and Diff Validation: Route requests through gateway behind feature flag. Run shadow mode: send requests to both monolith Lucene and new Search service; compare result sets field by field. Measure divergence; require < 0.01% for 48 hours before traffic ramp.
Gradual Traffic Ramp: 1% → 5% → 25% → 50% → 100% using feature flags and canary deployments. Rollback controller monitors latency and error rates; reverts flag if breach. Keep old Lucene index warm for two weeks post-cutover as rollback target.
Mobile App Verification: Verify mobile app behavior explicitly; it hits same endpoints. Test session persistence, offline search cache behavior, and app version compatibility during ramp.
Four-Stage Playbook: Execute Stages A–D as defined in Step 7. Stage A (shadow) lasts 1 week minimum. Stage B (read cutover) lasts 2 weeks. Stage C does not apply (reads only). Stage D (cleanup) after one peak or four weeks.
Soak Period: Land this extraction in open delivery window; soak at least four weeks before freeze (Dec 1 or June 1). No extraction reaches production less than four weeks before a freeze.
9. Extract Returns: Low-Stakes Proof of Four-Stage Playbook (after 5, 6, 7)
Second extraction and first write-path proof. Returns is chosen because it is off peak-critical path, has modest coupling, and exercises full four-stage playbook at low risk. Primary output is a proven, reusable procedure, not just one service.
Returns Service: Build with own schema. Consume order and customer events rather than joining their tables. Implement return state machine: Requested → Approved → Shipped → Received → Refunded.
Full Four-Stage Execution: Apply Stages A–D end-to-end with explicit recorded game day validating each stage rollback path. Stage A (shadow reads) for 1 week. Stage B (read cutover) for 2 weeks. Stage C (write cutover) with reverse CDC. Stage D (cleanup) after one peak or four weeks.
Rollback Rehearsal: Before write cutover, execute full game day: simulate service failure mid-cutover, trigger rollback (reverse CDC, flag flip, reconciliation), verify all data consistent, re-run golden master, confirm back-office queries still work. Record this session; play back monthly.
Back-Office Screens: Keep back-office returns screens on monolith for now (staff workflow untouched). Returns service is API-only; back-office integration comes later (Step 18).
Friction Point Capture: Record every operational friction, process gap, and test hole discovered during extraction. Update playbook from learnings. This step is as much about process validation as about extracting Returns.
Soak and Timing: Execute in open window; soak returns service for minimum four weeks before any freeze. Gate to proceeding to Inventory (Step 10) is successful four-week soak with zero rollbacks and full reconciliation agreement.
10. Extract Inventory: Warehouse Sync Improvement and Reservation Semantics (after 5, 6, 7)
Removes one of sharpest coupling points (15-minute file-exchange lag) and unblocks checkout work. Inventory runs in parallel with returns because it couples monolith to external warehouse system, not to other modules.
Inventory Service: Ingest warehouse feed directly (SFTP/API) instead of monolith polling. Design reservation semantics now: Reserve (place hold), Confirm (finalize after order), Release (cancel reservation on timeout/failure), with explicit timeout windows. Own stock levels and reservations per product per location.
Parallel Feeds During Transition: Run new ingest in parallel with legacy 15-minute feed. Reconcile hourly until both agree. This validates the new ingest does not miss updates or duplicate changes.
Monolith Inventory Tables as Projection: Keep monolith's inventory tables as read-only replicas fed by CDC from new service during Stage C (write cutover). Cart and checkout continue calling monolith queries unchanged during cutover; no checkout changes yet.
Four-Stage Execution: Apply Stages A–D. Stage A (shadow ingests and reads) for 2 weeks (must survive two 15-minute sync windows and validate no drift). Stage B (read cutover) for 2 weeks. Stage C (write cutover) with reverse CDC. Stage D (cleanup) after one peak.
Peak-Load Testing: Load-test inventory ingest at 12x (400k SKU updates/day during peak). Warehouse feed schedule and sales peaks do not always align; test worst-case concurrency. Validate no reservation deadlocks, no stock over-sells.
Cutover Order: Inventory read cutover must complete before Cart extraction (Step 13) to avoid monolith checkout calling new Inventory service via internal API during transition.
Soak and Gate: Soak minimum four weeks before freeze. Gate to proceeding to Customer (Step 11) is four-week soak with zero reconciliation mismatches and warehouse feed lag improved to < 2 minutes.
11. Extract Customer Accounts and Loyalty: Conservative Authentication Strategy (after 9, 10) from P2 · round 0 step 6
Extracts customer identity, profile, and loyalty programs. Authentication is deliberately placed late and guarded hardest because auth failures derail e-commerce migrations most often.
Customer Service: Own profile, address, and loyalty tables. Implement country-specific loyalty rules (8 countries, different point accrual rates) as data-driven rules where possible, code where not. Design API: GetCustomer, UpdateProfile, GetLoyaltyBalance, RedeemPoints, AccruePoints.
Authentication Strategy Phase 1: Keep authentication (login) in monolith for now. Customer service exposes only data APIs; token issuance remains monolith's responsibility. This delays risky auth cutover; less risk to peak season.
Distributed Session Handling: Introduce Redis-backed distributed sessions. Services can verify customer identity without querying monolith database. Implement token-validation API so services can verify bearer tokens without round-tripping to monolith.
Data Cutover: Execute four-stage playbook. Stage A (shadow reads) for 1 week. Stage B (read cutover) for 2 weeks. Stage C (write cutover) for new customers, address updates, loyalty accrual. Stage D (cleanup) after one peak.
Golden Master for All Countries: Golden master captures customer queries across all 8 countries, all 4 languages, and all loyalty-rule variations. Shadow-traffic diff must show < 0.01% divergence before read cutover.
Mobile App Session Behavior: Test mobile app's long-lived sessions explicitly; storefront does not hold sessions same way. Validate token refresh, session timeout, and app version compatibility during cutover.
Loyalty Accrual Last: Move loyalty point accrual and redemption last within this step (Stage C final substep). Loyalty error is customer-visible financial error, not technical incident; guard hardest.
Soak and Gate: Soak minimum four weeks. Gate to proceeding to Cart (Step 13) is successful loyalty accrual cutover with zero customer complaints and full reconciliation agreement.
12. Extract Cart: Stateful Session Service (after 6, 7, 10, 11)
Extract shopping cart, which is stateful and sits directly in front of checkout. Extracted before Pricing and Checkout because both depend on stable Cart boundary.
Cart Service on Redis: Build on Redis (or PostgreSQL with session affinity) for session and line-item state. Validate products and inventory through service API calls rather than direct database joins. Design API: AddItem, RemoveItem, UpdateQuantity, GetCart, ApplyCoupon, ClearCart.
Idempotent Operations: Every cart operation is idempotent. Retried add during peak does not duplicate line item. Retried remove is safe. Implement via unique constraint on (session, sku) or idempotency-key header.
Monolith Cart Tables as Projection: Keep monolith's cart tables as read-only projections fed by CDC from Cart service. Back-office screens continue reading old cart tables for abandoned-cart analytics (not yet migrated to service APIs in this step).
Four-Stage Execution: Apply Stages A–D. Stage A (shadow reads) for 1 week. Stage B (read cutover) for 2 weeks (use feature flag; gradual ramp 10% → 50% → 100%). Stage C (write cutover to service); Stage D after one peak.
Business Metric Monitoring: Cart latency surfaces as lost revenue (abandonment), not just error logs. Track cart abandonment rate and add-to-cart latency as primary success metrics during ramp.
Anonymous vs. Authenticated Carts: Test both paths separately; they follow different session-tracking mechanisms and fail in different ways. Ensure cart persists across login boundary.
Soak Before Freeze: Land in open window; soak minimum four weeks before freeze (Dec 1 or June 1). Gate to proceeding to Pricing (Step 14) is four-week soak with cart abandonment rate unchanged or improved and zero lost transactions.
13. Extract Pricing as Black Box Using Golden-Master Validation (after 5, 6, 7)
Extract 200k LOC pricing logic as-is without rewriting. Rules are not understood by anyone, so wrap and characterize rather than refactor. Rule decomposition deferred to follow-up program in writing.
Wrap Without Refactor: Move pricing code into dedicated service, unchanged. Service owns pricing tables post-cutover. Expose single decision API: ComputePrice(customerId, productId, locationId, timestamp, quantityId, loyaltyStatus) → {price, applicablePromotions, taxes, currency}.
Dependency Injection for Reads: Refactor pricing's dependencies so it obtains customer data via Customer service API, product data via Catalogue service API, inventory via Inventory service API. No direct cross-module database joins.
Golden-Master Validation: Run characterization test suite (built in Step 5) against new service. Require 100% output match on all 1M historical requests across all 8 countries, 3 currencies, 4 languages, all promotion types, edge cases. Any divergence blocks ramp; no exceptions.
Shadow Mode Duration: Run shadow traffic against live pricing requests for minimum four weeks, comparing every computed price with monolith. Measure divergence continuously. Divergence > 0.001% blocks ramp.
Gradual Cutover by Country: Cut over per-country rather than all-at-once. Start with lowest-revenue country, validate four weeks per country, then ramp to others. Per-country flags allow independent rollback.
Rollback Path: Keep monolith's pricing evaluator available and warm as rollback target for at least one full peak (January or July) after cutover. Maintain ability to flip back to monolith pricing via feature flag without data restore.
Four-Stage Playbook: Stages A–D applied to pricing tables. Stage A (shadow) 4+ weeks. Stage B (read cutover) 2 weeks per country. Stage C (write cutover) per country. Stage D (cleanup) after one full peak.
Deferred Refactoring in Writing: Publish decision that pricing rule decomposition, DSL, and optimization are explicitly deferred to follow-up program after this migration stabilizes. Include this in all project communications and retrospectives.
14. Extract Payment: PCI-Strict Regime and Provider-by-Provider Cutover (after 5, 6, 7)
Extract payment processing with stricter regime than any other service. Mistakes are irreversible and regulatory. Extracted before checkout orchestration because checkout cannot be decomposed without payment boundary.
Payment Service: Own integration with three payment providers (tokenization, authorization, capture, refund, provider webhooks). Design API: AuthorizePayment(idempotencyKey, amount, currency, cardToken, customerId) → {authorizationId, status}; CapturePayment(authorizationId); RefundPayment(captureId); HandleWebhook(webhookPayload).
PCI Scope Reduction: No raw card data at rest in service. Card data flows directly from client to provider (tokenization); only tokens stored in Payment service. Credentials in secrets management (Vault). No card data in logs or distributed traces.
Idempotent Operations: Explicit idempotency-key handling. Every payment request is idempotent; retries at peak are normal and must not double-charge. Implement via idempotency-key deduplication store (Redis with TTL).
Provider-by-Provider Cutover: Cut over one provider at a time (start with lowest-volume provider). Stage A (shadow) 2 weeks per provider. Stage B (read cutover, not applicable). Stage C (write cutover) for each provider, maintain fallback to monolith for other providers. Test each provider's decline, timeout, 3-D Secure, and chargeback scenarios explicitly.
Golden Master Scenarios: Golden master covers all three providers, all decline reasons, timeouts, partial authorizations, refund scenarios, chargebacks. Shadow traffic compares full payment outcomes (authId, status, amount, timestamp) before any live provider cutover.
Fraud Detection and 3-D Secure: These paths are usually least-tested and most visible when broken. Test explicitly; goldne master includes fraud-decline and 3-D Secure flows. Verify fraud rules and thresholds carry over unchanged.
Fallback Orchestration: Monolith retains ability to handle payment directly (as fallback) until second peak after Payment service cutover. Checkout can gracefully degrade to old payment path via feature flag if new service fails.
Four-Stage Playbook: Stages A–D per provider. Stage C (write) is highest-risk; ensure golden master passes 100% and shadow mode shows zero divergence before each provider cutover. Gate and soak strictly: four weeks minimum before any freeze.
Soak and Timing: Land in open window (Feb–May or Aug–Nov). Complete all three providers' Stage C cutover by month 9 to allow checkout orchestration time to soak before freeze.
15. Extract Orders: Event-Sourced Record of Truth (after 9, 13, 14)
Extract order management as authoritative record of order lifecycle. Extracted after Inventory, Pricing, and Payment exist and are stable, because Orders depends on all three.
Orders Service: Own order tables and order state machine. Implement explicit state transitions: Pending → Confirmed → Preparing → Shipped → Delivered, with validation blocking invalid transitions. Design API: CreateOrder(cartId, customerId, paymentAuthorizationId), GetOrder(orderId), CancelOrder(orderId), UpdateOrderStatus.
Event Sourcing: Record all order state changes as immutable events. Build order state from event log on demand. Audit trail satisfies regulators and fulfillment teams; state can be rebuilt after incidents. Include: OrderCreated, PaymentAuthorized, InventoryReserved, OrderConfirmed, OrderPreparing, OrderShipped, OrderDelivered, OrderCancelled.
Event Consumption: Consume events from Payment service (PaymentAuthorized, PaymentFailed), Inventory service (StockReserved, ReservationCancelled), and Returns service (ReturnInitiated, RefundIssued) rather than polling or joining.
Four-Stage Playbook: Stages A–D. Stage A (shadow) for 1 week. Stage B (read cutover) for 2 weeks, with gradual flag ramp. Five teams that query orders start reading from Orders service via API. Stage C (write cutover): new orders written to Orders service; monolith order tables become reverse-CDC read-only replicas. Stage D after one peak.
Reconciliation: Monetary and Row-Count: Reconcile order counts and monetary totals hourly against monolith throughout transition. Currency totals must match exactly (cent-by-cent); row count discrepancies are immediate rollback. Implement automated reconciliation query; owner assigned; threshold zero.
Concurrent Order Transitions: Load-test concurrent order state transitions at 480k/day peak. Order state machine becomes serialization point for distributed system; ensure no race conditions, no duplicate orders, no lost transactions.
Soak Before Checkout: Complete Orders cutover (Stages A–C) by month 9. Soak minimum four weeks before freeze. Gate to proceeding to Checkout (Step 16) is four-week soak with zero monetary reconciliation mismatches and zero order duplicates.
16. Extract Checkout: Distributed Saga Orchestration (Highest Risk) (after 12, 13, 14, 15) from P3 · round 1 step 10
Highest-risk extraction, deliberately placed last among transactional work and only after components it orchestrates are individually proven at scale. This step composes independent services into coherent checkout flow.
Checkout Orchestrator Service: Build service that coordinates checkout: cart validation, price computation, inventory reservation, payment authorization, order creation. Design as explicit saga with named steps and compensating actions.
Saga Orchestration: Implement synchronous saga (single coordinator) or asynchronous (choreography via events), chosen based on latency testing (target checkout p99 < 5 seconds at peak). Synchronous preferred for checkout because customer waits; failure is visible. Steps:
- Validate cart via Cart service
- Compute price via Pricing service (cached if < 1 second old)
- Reserve inventory via Inventory service
- Authorize payment via Payment service
- Create order via Orders service
Compensating Transactions: For every step, define compensation:
- Step 3 fails: Release inventory reservation
- Step 4 fails: Release inventory reservation, void authorization (if possible)
- Step 5 fails: Release reservation, void authorization, return payment to customer
- Step 2 recomputes and differs: Increase price, reject order; or decrease price, accept at old price (business rules decision, document explicitly)
Idempotency End-to-End: Checkout request includes idempotency key (unique per browser session + timestamp). Service deduplicates on this key. Retried checkout cannot double-charge or double-reserve; returns previous result.
Timeout Handling: Inventory reservation expires in 15 minutes (configurable). Payment authorization valid for 7 days (provider-specific). Order creation never times out; if hanging, manually investigate. Saga must fail safe to retryable state, never to half-committed order.
Shadow Traffic Before Live: Mirror live checkout traffic (100% of checkout requests during business hours) to new orchestration for minimum 2 weeks before any live cutover. Compare full outcomes: order ID, order total, inventory reservations, payment authorization IDs, error messages. Divergence > 0.001% blocks live cutover.
Live Ramp During Open Window: Ramp live traffic only during open delivery window (Feb–May or Aug–Nov). Gate and soak strictly: minimum four weeks before freeze. Keep monolith checkout path fully functional and warm (receiving live traffic via feature flag) as rollback target until Checkout service has survived one full peak.
Peak-Readiness Gate Mandatory: Hold six-week peak-readiness gate (Step 19) before proceeding to back-office migration (Step 18). Failed gate stops this work immediately and defers to next window.
17. Migrate Back-Office, Storefront, and Mobile Clients to Service APIs (after 16) from P2 · round 1 step 17
Moves 300 back-office staff and client applications off monolith database direct access. Until this step, monolith database remains live dependency even where logic moved.
Back-Office Screen Refactoring: Migrate screens table by table. Replace direct SQL with service API calls through gateway. Start with orders (call Orders service), then customers (call Customer service), then inventory (call Inventory service). Build aggregation endpoints: /orders/{id}/full-details calls Orders + Payments + Inventory + Returns services, caches 30 seconds, returns unified response.
Aggregation Endpoints and Caching: Services are now call-chain away, not co-located. Back-office latency would suffer without caching. Implement short-lived cache (TTL 30 seconds) for frequently accessed data (customer profiles, recent orders). Graceful degradation: if one service slow, show cached data and alert staff.
Storefront and Mobile App: Both hit same endpoints (via gateway). Update storefront (server-rendered) to call service APIs while keeping old path functional behind feature flag; rendering regression becomes flag flip, not rollback. Mobile app points at gateway for migrated endpoints; keep old endpoints alive for un-updated app versions (users do not upgrade on schedule). Implement API versioning: v1 (legacy monolith), v2 (service APIs); clients request version in Accept header.
API Versioning and Deprecation Windows: Publish versioning rules: breaking changes trigger major version bump (v2 → v3). Old version supported for minimum 90 days after major release. Client teams must upgrade within window; do not force upgrade. Document deprecation timeline in API spec.
Load Test Back-Office Concurrency: Test 300 concurrent staff on top of peak storefront (480k orders/day). New services now carry both loads; autoscaling and database connection pools must handle burst. Simulate realistic staff queries: order searches, customer history, bulk refunds.
Distributed Tracing for Debugging: Every back-office request traced across services. Staff can view trace in UI; operations team can see which service was slow. Trace includes: request start, service calls, database queries, cache hits/misses.
Monitoring and Runbooks: Create runbooks for common issues: slow customer search (check Customer service load), payment lookup fails (check Payment service), order create fails (check Orders service latency). Link from dashboard to runbook.
Gate to Monolith Decommissioning: Back-office must be fully migrated (no direct SQL reads to monolith) before monolith core decommissioning (Step 18). This step completes organizational cutover.
18. Chaos Engineering, Resilience Testing, and Pre-Peak Validation (after 17)
Validates new distributed architecture survives failure scenarios and peak load without cascading collapse. This step is as much about proving state is coherent as about finding failure modes.
Chaos Game Days: Scheduled monthly (or before each peak). Kill each service in turn (Search, Inventory, Orders, Payments, etc.); confirm storefront degrades gracefully (e.g., 'Search temporarily unavailable, catalog browsing still available') rather than failing completely. Kill database replicas; verify service continues with read-only or cached data. Kill message broker; verify no events lost and no reordering. Record each game day; publish findings and mitigation actions.
Peak-Readiness Gate (Before Each Peak): Run six weeks before January and July peaks (mid-November, mid-May):
- 12x Load Test: Generate realistic 480k orders/day traffic against production-shaped data (8 countries, 3 currencies, 4 languages, realistic product hierarchy). Measure checkout p99 < 5 seconds, search p95 < 1 second, payment < 2 seconds.
- Capacity Headroom: Confirm all services autoscale to handle 12x baseline. Database connection pools have headroom. Message broker partitions are sufficient. Cache hit rates do not collapse under load.
- Rollback Rehearsal: Execute full rollback of most recent service extraction in load-test environment. Measure rollback time; must be < 30 minutes including data reconciliation.
- Error Budget Review: Confirm SLO error budgets not burned significantly. If burned, identify culprit and mitigate before peak.
- Evidence Publication: Publish load-test results, capacity headroom metrics, rollback time, and SLO status. Gate is pass/fail; failed gate defers peak exposure and triggers root-cause work.
Full System Load Test: All services under load simultaneously. Measure inter-service latencies, database load, message broker throughput. Identify bottlenecks: pricing calculations, search queries, payment provider round-trip time, inventory reservations under concurrent access. Tune:
- Database query indexes
- Connection pool sizes
- Caching strategies
- Message broker partitions
- Service autoscaling thresholds
Failure Mode Analysis: Identify top 10 single-point-of-failure risks:
- Payment provider outage → graceful degradation (pre-authorize smaller amounts?)
- Inventory service down → checkout blocked; mitigation: cache inventory in checkout orchestrator
- Pricing service down → checkout blocked; mitigation: cache last-known prices
- Orders service down → checkout blocked; mitigation: queue orders in Kafka, replay when service recovers
- Database down → all services blocked; mitigation: read-only replicas for queries
- Message broker down → no events published; mitigation: outbox patterns ensure no event loss
- API gateway down → all traffic blocked; mitigation: active-active gateway setup (two regions or multiple providers)
- Warehouse sync delayed → inventory stale; mitigation: alert threshold, manual intervention process
- Customer service down → login blocked; mitigation: cache tokens, allow anonymous checkout
- Search service down → browsing blocked; mitigation: fallback to category list without search
For each failure, document mitigation (architectural change or operational procedure), test in chaos game day, and update runbooks.
Synthetic Transaction Monitoring: Implement real-world checkout, return, and search transactions executing every five minutes. Alert on failure before customers notice. Include multi-country, multi-currency variations.
Performance Baseline Documentation: Document baseline latencies (checkout, search, payment) at baseline load (40k orders/day). Load test must show no regression at peak; improvements accepted. Document these baselines in runbooks for operations team reference.
19. Monolith Decommissioning and Steady-State Operations (after 18)
Safely retire monolith code once all services stable and production-proven. This step is final validation that new architecture is coherent; incomplete decommissioning signals hidden coupling.
Module-by-Module Cleanup: Delete extracted service code from monolith only after that service has survived one full peak (January or July, whichever comes first) or four clean weeks post-cutover, whichever is longer. Before deletion:
- Audit dead code: which stored procedures, views, tables, methods are no longer called
- Verify service API is the only interface for data owned by extracted module
- Confirm no service calls back into monolith code
- Delete extracted logic and dependencies
Database Decommissioning: Dropped tables are archived (not deleted) for 90 days (regulatory retention and emergency queries). After 90 days, drop and archive to long-term storage. Monolith database shrinks as modules extracted. When monolith becomes shell (mostly unused), decide: keep as fallback or shut down entirely.
Cross-Module Stored Procedures: All stored procedures touching multiple modules' tables must be eliminated before monolith shutdown. If any remain, move logic into services or refactor. Document any that cannot be moved; escalate as risk.
Backup and Recovery Procedures: Shift from single monolith snapshot to per-service snapshots. Each service team owns backup/recovery for their database. Document recovery procedures: which services recover in which order, which can tolerate data loss vs. which require point-in-time recovery. Test recovery monthly.
Architectural Decision Records: Publish final ADRs documenting:
- Why services were split at these boundaries
- What problems each split solved
- What trade-offs were made
- What cross-service communication patterns emerged
- What monitoring and alerting proved most useful
Operational Runbooks: Finalize runbooks for each team:
- Incident response: common failure modes, resolution steps, escalation paths
- Deployment procedures: how to deploy service, rollback procedure, expected latency
- On-call procedures: alert thresholds, page-worthy events, war room communication
- Database procedures: backup, restore, schema migrations, connection pool tuning
Service Ownership Model: Confirm each of five teams owns one or more services end-to-end:
- Codebase and CI/CD pipeline
- Database schema and migrations
- On-call rotation and SLOs
- Production incidents
- Capacity planning and scaling
No shared ownership; clear escalation paths between teams.
Team Ramp-Down of Migration Work: Migration enablement squad (formed in Step 1) transitions into steady-state platform team. Reduce migration velocity; redirect capacity to feature work on services.
Exit Criteria and Project Close:
- All rungs 1–6 of scope ladder complete (or deliberately stopped at rung boundary)
- Both peak seasons (January and July) survived without migration-caused incidents
- All services deployed independently by month 12
- Monolith reduced to < 5% of original codebase or decommissioned entirely
- All architectural decisions documented and team alignment confirmed
Celebrate and Document Lessons: Publish retrospective capturing:
- What went well: which techniques proved most valuable (golden master? chaos testing? soak periods?)
- What was hard: which services took longer, which risks materialized
- What would change next time
- Which rungs of scope ladder were reached and why work stopped where it did
Deferred Work: Explicitly list architectural or optimization work deferred to follow-up programs (e.g., Pricing DSL refactoring, read-write split at database level, multi-region deployment).
20. Peak Season Validation and Post-Peak Stabilization (after 18, 19)
Proves new architecture survives peak and validates migration is truly complete. January and July peaks are the final test; this step verifies readiness and documents learnings.
Pre-Peak Confirmation: One week before peak start (Dec 25 for January peak, June 25 for July peak), confirm:
- All peak-readiness gate checks passed
- All services healthy and responding normally
- Database connection pools at capacity
- Cache hit rates normal
- Message broker lag within SLOs
- On-call rotations staffed
- War room communication channels open
Peak Monitoring: During peak (480k orders/day sustained for 2–3 weeks), maintain heightened monitoring:
- Every service dashboard visible in central war room
- Latency p99, p95, p50 trending in real time
- Error rate per service alarmed
- Database query performance monitored
- Message broker lag tracked
- Payment success rate watched (fraud filters, authorizations)
- Inventory reservation accuracy validated hourly
Incident Response: Any incident < 5 min MTTR automatically escalates to war room. Team lead validates:
- Root cause (service slow? database? payment provider?)
- Impact (customer-visible? checkout blocked? data corruption?)
- Mitigation (rollback flag? scale service? throttle traffic?)
- Recovery (how long to resolve?)
Post-Peak Retrospectives: Within one week of peak completion, each service team retrospectives on:
- Peak traffic patterns observed vs. load-test simulations
- Any incidents: root cause, time-to-detect, time-to-recover
- Performance variations: which services scaled, which became bottlenecks
- Data accuracy: any reconciliation mismatches discovered during peak
- Lessons for next peak
Capacity Planning: After peak, analyze:
- Database query times at peak: any unexpected slowdowns?
- Service autoscaling: did services scale early enough? were there cascading failures?
- Cache effectiveness: hit rates at peak vs. baseline
- Message broker: any message loss or reordering?
- Payment provider latency: did provider response times increase during peak?
Final Validation: Confirm scope ladder rung achieved:
- Rung 6 complete: back-office migrated, monolith core reduced, checkout orchestration stable
- Teams deployed independently during peak (or blocked from deploying due to freeze, which is correct)
- Zero unplanned downtime caused by migration
- All rollback procedures worked in chaos testing; never needed in production
Program Closure: Publish final evidence:
- Peak season metrics (order volume, success rate, latency, errors)
- Service-by-service stability (uptime, incidents, MTTR)
- Scope ladder rung reached
- Explicit deferred work list
- Team feedback and lessons learned
Next Program Planning: If rung 7+ desired (e.g., Pricing rules DSL refactoring, multi-region deployment), plan as separate 6-month program. Document in writing; do not creep scope into current program.
- Zero unplanned downtime: 100% availability throughout 12-month migration (excluding planned 30-min blue-green deployments); no production incidents attributable to migration architecture
- Peak seasons protected: January and July peaks (480k orders/day) sustain zero degradation caused by migration; checkout p99 ≤ 5 seconds, payment authorization ≤ 2 seconds, error rate ≤ 0.5%, no queue backlog > 5 minutes
- Independent deployability: All eight services independently deployable by month 12; each team releases on own cadence (weekly or faster) with zero cross-team deployment coordination; 100% of service releases verified rollback-capable in < 30 minutes
- Rollback-proven: Every production increment has rehearsed, documented, tested rollback path (expand/contract migrations, feature flags, reverse CDC); monthly chaos game days validate rollback procedures; zero increments reach production without passing rollback gate
- Data consistency: Hourly reconciliation shows < 0.001% row-count and checksum discrepancy between service databases and monolith (pre-decommissioning); zero business-invariant violations (no duplicate orders, no lost payments, no inventory oversells)
- Pricing correctness: 100% agreement between new Pricing service and golden-master corpus across 1M+ historical requests covering all 8 countries, 3 currencies, 4 languages, all promotion types; zero pricing errors post-cutover
- Search freshness: Product availability reflects in search within < 60 seconds of inventory change (vs. nightly rebuild); search latency p95 unchanged or improved at peak load
- Warehouse sync improvement: Inventory synchronization lag reduced from 15 minutes to < 2 minutes end-to-end; 100% of daily warehouse updates processed; no missed sync cycles during migration
- Payment processing: Zero regressions with all three payment providers; fraud detection active and effective; PCI-DSS compliance maintained; idempotency prevents duplicate charges; payment success rate ≥ 99.5% at peak
- Back-office operations unaffected: All 300 staff seamlessly using service APIs; service aggregation endpoints maintain p95 latency ≤ 500 ms; bulk operations (refunds, order status updates) complete within SLA
- Test coverage for services: All newly written service code reaches 80%+ line coverage; golden master validates 100% of public API contracts before production traffic; contract tests (Pact) prevent breaking changes between services
- Peak-readiness gate passed: Six weeks before each peak (mid-November, mid-May), gate published showing 12x load test results, capacity headroom, rollback rehearsal duration, and SLO status; failed gate defers work; evidence published publicly
- Team independence by month 12: Five teams deployed independently; each owns service codebase, pipeline, database schema, on-call rotation, SLOs; no cross-team pull requests blocking releases; internal developer platform (golden-path templates, self-service deployments) adopted by all teams
- Scope ladder completed: Rungs 1–6 reached by month 12 (or deliberately stopped at rung boundary with documented justification); all services proven at peak; monolith reduced to < 5% or decommissioned
- Calendar adherence: No major extractions or refactors during freeze windows (Dec 1–Jan 15, June 1–July 15); all production increments land in open windows with minimum 4-week soak before freeze; timeline published and adhered to
- Event-driven architecture validated: Kafka message broker handles 480k+ messages/day at peak; no message loss, no ordering violations; outbox pattern ensures every domain event persists atomically
- Fallback capacity maintained: Monolith rollback path kept warm and functional (receiving live traffic or ready-to-receive via feature flag) until each service survives one full peak; no service extracted without proven rollback capability
Evolution analysis
The analysis in brief
At a glance
- Analyst's first choice, blind to the vote: proposal 2 · deepseek-flash_refine_2
- The vote: proposal 1 · claudeHaiku4.5_refine_1 — the analyst disagrees
- Against the initial proposals: better than every initial proposal
- Rounds: round 1 converging · round 2 converging
- The process: 3 problems observed, 3 suggestions
The final round, in the analyst's words
The final round presents highly mature, constraint-driven migration plans that correctly prioritize peak-season safety and data decoupling over naive service extraction. The proposals converge on a calendar-first approach, golden-master characterization for the pricing module, and a four-stage cutover playbook, demonstrating strong learning from prior rounds.
Raw prompts and responses of every analysis call
[ROUND 0]
[SYSTEM]
You are an expert reviewer of multi-agent planning processes.
Several LLM agents drafted plans for a task, refined them over a number of rounds while seeing each other's proposals, and finally voted for the best one.
Be exhaustive but precise: name concrete steps, ideas and metrics, never generalities. Judge plans by their fitness for the task as stated, their realism, their completeness, the soundness of their order and dependencies, how measurable their success is and how they handle things going wrong.
You are an impartial evaluator, not a chronicler: assess the proposals and the process on their merits, never rationalise what happened or assume that the outcome was right.
After your analysis, answer in the requested structure.
Every text field you write will be read by a busy person, so write for them: short sentences, one idea each, in short paragraphs. Text fields accept Markdown: separate paragraphs with a blank line, use a bullet list when you enumerate things and plain paragraphs when you explain or argue, and bold at most one key phrase per paragraph. A text of more than three sentences must be split into paragraphs; never deliver a single unbroken block of text.
[HUMAN]
Task given to the agents: "A mid-size European fashion retailer runs its e-commerce on a 10-year-old monolith: Java 8 / Spring, about 2 million lines, one PostgreSQL database of 1.2 TB with 350 tables and heavy use of stored procedures and cross-module joins. It serves 8 countries, 3 currencies and 4 languages, with about 40,000 orders a day and peaks of 12x during sales. The monolith contains: the storefront (server-rendered, plus a separate mobile app hitting the same endpoints), catalogue and search (a Lucene index rebuilt nightly), pricing and promotions (the most complex module, 200,000 lines, with country-specific rules nobody fully understands), cart and checkout with three payment providers, order management, inventory synchronised every 15 minutes with the warehouse system via file exchange, customer accounts and loyalty, returns, and a back-office used by 300 staff. Deployments happen every two weeks as a single artefact with a 30-minute maintenance window; test coverage is 25% and mostly unit tests. Five teams of 8 developers, each organised around a business area but all committing to the same repository.
Plan the migration to independently deployable services over 12 months with no feature freeze, no unplanned downtime and the ability to roll back every step, preserving the peak-season capacity (sales in January and July must not be put at risk)."
This is round 0: every agent wrote its plan independently, without seeing the others.
--- PROPOSAL 1 (agent claudeHaiku4.5_initial_1, anthropic/claude-haiku-4-5) ---
Estimated complexity: high
Success metrics: - All 8 services independently deployed and running in production with zero unplanned downtime during 12-month migration
- Zero data inconsistencies between service-specific databases (validated by monthly reconciliation)
- January and July peak seasons proceed with no degradation: 480k orders/day processed within 5-second checkout SLA
- Test coverage increased from 25% to 70%+ for all extracted services
- Every service deployment is fully automated; manual rollback procedures tested and <30 minutes to execute
- Order processing latency (cart → confirmation) unchanged or improved: maintained under 5 seconds at peak load
- All 5 teams deploying independently: no cross-team deployment coordination required after cutover
- Pricing/promotions service successfully extracted with all 200k LOC of country-specific rules preserved and validated
- Search latency improved or maintained despite architectural change
- Inventory synchronization with warehouse continues reliably: no missed 15-minute sync cycles
- Back-office operations for 300 staff members unaffected by migration; service aggregation endpoints maintain <500ms latency
- Zero payment processing regressions: all three payment providers functioning, fraud detection active, PCI-DSS compliance maintained
Steps (24):
1. Current State Documentation & Target Architecture
Create a detailed map of the monolith to inform service extraction strategy.
- Audit all modules: storefront, catalogue, search, pricing/promotions, cart, checkout, orders, inventory, customers, loyalty, returns, back-office
- Map dependencies between modules, identifying cross-module calls and data flows
- Model future bounded contexts using Domain-Driven Design
- Create technology inventory (libraries, frameworks, protocols)
- Document interface contracts for each module
- Identify which teams own which modules for organizational alignment
2. Data Dependency Analysis & Dual-Write Strategy (depends on: 1)
Untangle the 1.2TB database to support service independence without blocking progress.
- Map all 350 tables to future service domains
- Identify cross-service joins and stored procedures that span domains
- Design per-service database schemas with minimal denormalization
- Create data versioning framework to support rollback
- Plan dual-write patterns: how old monolith and new services will sync during transition
- Document eventual-consistency requirements and conflict resolution
- Design data migration runbooks with clear rollback steps
3. Test Coverage Audit & Improvement Roadmap (depends on: 1)
Build confidence for service extraction by eliminating test blindness.
- Audit current 25% test coverage by module
- Identify coverage gaps in modules scheduled for early extraction
- Establish target of 70%+ coverage for modules being extracted
- Prioritize integration tests over unit tests given monolith complexity
- Create quality gates: no service extraction below 60% module coverage
- Plan for continuous improvement during extraction phases
4. Peak-Season Window Planning & Risk Framework (depends on: 1)
Protect January and July sales by scheduling extractions during safe windows.
- Map annual peak periods: January sales (peak orders), July sales, plus any promotional events
- Define 4-week freeze windows before/during peaks
- Identify lowest-risk windows in each month for major changes
- Create rollback procedures that execute in <30 minutes
- Establish monitoring escalation for changes made near peak season
- Document communication plan with business teams
5. Observability Foundation Setup
Instrument the system for real-time visibility during migration.
- Deploy centralized logging (ELK, Splunk, or similar)
- Set up metrics collection (Prometheus, Datadog, or similar)
- Implement distributed tracing (Jaeger, Zipkin) for request flows across services
- Create dashboards for: requests/sec, error rates, latency percentiles, database load
- Define SLOs: order processing latency p99, checkout success rate, payment authorization speed
- Set up alerts for SLO violations and anomalies
6. Feature Flags, Containerization & API Gateway
Build the technical foundation for canary deployments and controlled traffic routing.
- Implement feature flag system (LaunchDarkly, custom Spring Boot solution, etc.)
- Containerize monolith and all new services (Docker)
- Set up container orchestration (Kubernetes or similar) with service templates
- Deploy API gateway (Kong, AWS ALB) with routing rules
- Implement service-to-service authentication (mTLS, JWT)
- Configure rate limiting and circuit breakers at gateway
7. Deployment Pipeline & Automated Rollback (depends on: 6)
Enable safe, automated deployments with reliable rollback capability.
- Implement CI/CD pipeline with automated testing gates
- Set up blue-green deployment: run old and new versions in parallel, switch traffic atomically
- Build canary deployment capability: route 5%→10%→50%→100% of traffic gradually
- Automate rollback: trigger on error rate threshold, latency spike, or manual command
- Create deployment runbooks for each service
- All deployments must be independent; monolith keeps 2-week cycle until fully extracted
8. Test Coverage Improvement to 70%+ (depends on: 3)
Close test gaps before extracting services to reduce rollback risk.
- Implement integration tests for key flows: order creation, payment processing, inventory updates
- Add contract tests between modules to catch breaking changes
- Use mutation testing to verify test quality
- Target 70%+ coverage for: pricing module, payment module, order management
- Establish automated quality gates: coverage <70% blocks extraction of that service
- Include tests for peak-load scenarios (40k→480k orders)
9. Search/Catalogue Service Extraction & Validation (depends on: 7, 8, 3)
Extract the first service: search is read-heavy, isolated, and low-risk.
- Extract catalogue and search indexing logic from monolith
- Build as independent Spring Boot service with own codebase/deployment
- Create new database schema for catalogue (subset of 350 tables)
- Implement dual-write: monolith writes to both old Lucene index and new service
- Implement canary routing: API gateway sends 10% of search requests to new service, monitor latency and correctness
- Validate results match between old and new service (checksums on result sets)
- Gradually increase traffic: 10%→25%→50%→100%
- Keep dual-write active for 2 weeks post-cutover for rollback safety
10. Event Bus & Service Mesh Infrastructure (depends on: 9)
Build async communication layer required for multi-service coordination.
- Deploy message broker (Kafka recommended for ordering guarantees and peak load of 40k/sec)
- Define domain events: OrderPlaced, PaymentAuthorized, InventoryReserved, etc.
- Implement event schema versioning and compatibility
- Set up service discovery (Consul, Kubernetes DNS)
- Implement distributed configuration management
- Create event publishing library for services to use
- Document saga patterns for multi-step workflows
- Test message broker under peak load (480k messages/day)
11. Inventory Service Extraction & Warehouse Sync (depends on: 10)
Extract inventory as second service: well-bounded, drives warehouse sync complexity.
- Extract inventory logic and reservation system
- Build inventory service with own database schema
- Implement dual-write from monolith to both old and new inventory data
- Preserve existing 15-minute warehouse file exchange, but now via service
- Create inventory events: ReservationCreated, ReleaseRequested
- Implement canary rollout: gradual traffic shift like search service
- Test warehouse sync under peak load
- Validate inventory consistency across monolith and new service before full cutover
12. Customer/Loyalty Service Extraction & Auth Refactoring (depends on: 10)
Extract customer accounts and loyalty: enables independent scaling of auth layer.
- Extract customer account and loyalty program logic
- Build customer service with own database schema
- Separate authentication from monolith: implement API for token validation
- Support multi-tenant loyalty rules (8 countries, country-specific points rules)
- Implement canary rollout with real customer sessions
- Create backwards-compatible customer APIs
- Test account operations at peak concurrency (concurrent logins, loyalty point updates)
- Plan for session management: ensure distributed sessions work across services
13. Saga Pattern Library & Order Orchestration Framework (depends on: 10)
Build the framework for managing distributed transactions across services.
- Implement saga pattern library: choreography-based (event-driven) and orchestration-based patterns
- Support compensating transactions: if payment fails, return inventory reservation
- Handle timeouts and retries with exponential backoff
- Implement idempotency keys to prevent duplicate charges on retries
- Test saga execution under peak load and network failures
- Document patterns for: order placement saga, payment saga, return saga
- Create distributed tracing for saga flows
14. Pricing/Promotions Service Extraction (Phase 1: Extract As-Is) (depends on: 13)
Begin extraction of most complex module (200k LOC) without initial refactoring.
- Extract pricing engine as-is with minimal refactoring to reduce initial risk
- Preserve all country-specific rules and business logic
- Build service boundary: accept pricing requests, return prices/promotions
- Create feature tests that document all 200k LOC behavior
- Map all promotion types to test scenarios
- Test with real country/currency/language combinations
- Implement as service behind same interface initially
- Prepare for Phase 2 refactoring once stable in production
15. Pricing/Promotions Service Refinement (Phase 2: Rules Refactoring) (depends on: 14)
Gradually improve pricing service maintainability without breaking production.
- Document the 200k LOC of complex rules in machine-readable format
- Refactor rules engine into composable components
- Build DSL for country-specific promotion rules
- Decompose monolithic rule evaluation into smaller decision trees
- Use feature flags to A/B test refactored rules vs old implementation
- Optimize performance: reduce calculation time for promotions at checkout
- Validate that refactored logic matches original behavior across all countries
16. Payment Service Extraction & Security Hardening (depends on: 13)
Extract payment processing with extreme rigor given PCI/regulatory requirements.
- Separate payment logic from checkout: payment validation, three-provider integration
- Build payment service with encrypted credential storage, no raw card data in logs
- Implement fraud detection integration and decline handling
- Audit for PCI-DSS compliance: minimal data exposure, encrypted transport
- Implement E2E testing for all three payment provider scenarios
- Load test payment service: 500+ payments/sec at peak
- Implement idempotent payment requests: prevent double-charging on failures
- Create detailed rollback procedures: how to fall back to direct monolith payment handling
17. Order Service Extraction & Event Stream (depends on: 13, 16)
Extract order management: central service coordinating multiple workflows.
- Extract order creation, status tracking, and management logic
- Build order service with event stream: OrderCreated, PaymentAuthorized, InventoryReserved, OrderConfirmed
- Support order querying by all 5 teams (inventory, fulfillment, customer service, etc.)
- Implement order event sourcing for audit trail and replay capability
- Create order state machine: validate state transitions
- Test concurrent order processing at peak load (40k orders/day)
18. Checkout Service Composition via Saga (depends on: 17)
Compose checkout from independent payment, inventory, and order services using sagas.
- Build checkout service that orchestrates: cart validation → pricing calculation → inventory reservation → payment authorization → order creation
- Use saga pattern: if payment fails, release inventory reservation automatically
- Implement distributed transaction semantics: all-or-nothing guarantee
- Support three payment providers transparently
- Test all failure scenarios: payment declines, inventory unavailable, warehouse system down
- Implement timeout handling: what happens if inventory service is slow at peak
- Validate checkout latency remains <5 seconds at peak load
19. Back-Office Integration with Service APIs (depends on: 18)
Update back-office (used by 300 staff) to coordinate across all services.
- Create service aggregation endpoints: orders endpoint calls order service + payment service + inventory service
- Update back-office UI to call new service APIs instead of monolith
- Implement service discovery: handle service availability transparently
- Create caching layer: reduce latency for frequently accessed data
- Test with 300 concurrent staff users
- Implement search across all orders/customers via service APIs
- Add retry logic and timeouts to handle service failures gracefully
20. Storefront & Mobile App Refactoring (depends on: 19)
Update client applications to use new service architecture transparently.
- Update server-rendered storefront templates to call service APIs
- Update mobile app endpoints (already separate, now points to services via gateway)
- Implement client-side caching: reduce latency impact of distributed calls
- Maintain backwards compatibility: old clients must still work
- Update API versioning: enable service changes without breaking clients
- Implement request tracing: correlate user requests across services
- Test storefront and mobile under peak load scenario (480k orders/day)
21. Legacy Database Deprecation & Data Migration (depends on: 20)
Safely decommission the monolith database once all services are independent.
- Verify all data has been migrated to service-specific databases
- Maintain 2-week read-only access to old database for emergency queries
- Archive old database snapshots (regulatory requirement for order history)
- Update backup/recovery procedures: now per-service instead of monolith
- Verify no remaining cross-service joins depend on monolith schema
- Document data mapping for future reference
- Decommission old database infrastructure
22. Load Testing & Performance Optimization (depends on: 21)
Validate new architecture meets production capacity requirements.
- Simulate peak load scenario: 480k orders/day (40k baseline × 12)
- Test across 8 countries, 3 currencies, 4 languages simultaneously
- Identify bottlenecks: service latency, database query performance, message broker throughput
- Optimize hot paths: pricing calculations, search queries, payment processing
- Test cache effectiveness: Lucene search response times, pricing cache hit rates
- Validate database connection pools don't exhaust under peak load
- Create load testing environment: realistic data, all 5 teams' concurrent usage
23. Documentation & Knowledge Transfer (depends on: 22)
Codify migration experience and new architecture for long-term success.
- Document final service boundaries: APIs, responsibilities, data ownership
- Create operational runbooks: how to deploy each service, how to handle common failures
- Record architecture decision log: why services were split this way
- Document data consistency model: eventual consistency patterns used
- Create troubleshooting guides: common issues and resolutions
- Train each team on their service and API contracts with other services
- Record key decisions and trade-offs (e.g., why search is separate from catalogue, why pricing is monolithic within its service)
24. Production Stabilization & 30-Day Monitoring (depends on: 23)
Establish stable operation and prove architecture meets requirements.
- Run 30-day monitoring period observing: error rates, latency, resource utilization
- Establish performance baselines: P99 latency per service, throughput, error rates
- Document SLO achievements: order processing speed, payment success rate, search latency
- Create incident playbooks based on observed issues
- Validate peak-load handling (Jan/July sales go normally through new architecture)
- Establish team on-call procedures for service alerts
- Plan for service scaling: autoscaling policies, capacity planning
- Complete full rollback verification: ensure rollback to monolith is always possible
--- PROPOSAL 2 (agent deepseek-flash_initial_2, deepseek/deepseek-flash) ---
Estimated complexity: high
Success metrics: - 100% of planned service extractions completed within 12 months.
- Zero unplanned downtime during January and July peak sales.
- All new services independently deployable with <5 minute lead time.
- 100% of deployments rollback-able within 5 minutes.
- 80% of traffic served by new services by end of 12 months.
- Test coverage increased to 60% for critical modules.
- Deployment frequency increased from bi-weekly to daily.
- Mean time to recovery (MTTR) < 30 minutes.
- Change failure rate < 15%.
- All stored procedures refactored or migrated to services.
- Database decomposed into 5+ independent databases.
- Peak load capacity sustained at 12x with <1% error rate.
Steps (15):
1. Mobilize Program and Define Target Architecture
Launch the migration program and define the target architecture. This step sets the foundation for all subsequent work.
Key activities:
- Establish a steering committee with business, architecture, and operations representatives.
- Conduct domain-driven design workshops to identify bounded contexts and service candidates.
- Define the target architecture: API gateway, service mesh, event-driven integration, and data ownership per service.
- Prioritize service extraction based on business value, risk, and coupling.
- Create architecture decision records (ADRs) and a service roadmap.
Output: a shared vision and prioritized backlog for the migration.
2. Build Platform Foundation for Independent Deployments (depends on: 1)
Build the platform foundation required for independent deployments. This includes infrastructure, tooling, and golden paths.
Key activities:
- Provision a Kubernetes cluster with namespaces for each service.
- Set up CI/CD pipelines per service using GitLab CI or ArgoCD.
- Deploy an API gateway (e.g., Kong) and service mesh (e.g., Istio) for traffic management.
- Implement observability: centralized logging (ELK), metrics (Prometheus/Grafana), and tracing (Jaeger).
- Set up secrets management (Vault) and configuration management.
- Create golden path templates for new services to reduce boilerplate.
Output: a production-ready platform where teams can deploy services independently.
3. Implement Strangler Fig Facade and Monolith Instrumentation (depends on: 2)
Implement the strangler fig facade and instrument the monolith. This allows incremental migration without disrupting users.
Key activities:
- Deploy the API gateway to route requests to the monolith or new services based on path or header.
- Modify the monolith to expose REST APIs for key domains (e.g., catalogue, customer).
- Implement the transactional outbox pattern to publish domain events from the monolith.
- Set up change data capture (CDC) from the monolith PostgreSQL to Kafka using Debezium.
- Introduce feature flags for routing and canary releases.
- Ensure all changes are backward compatible and can be rolled back.
Output: a facade that enables gradual traffic shifting and a data pipeline for synchronization.
4. Establish Continuous Delivery and Test Automation (depends on: 1)
Establish continuous delivery and test automation to support safe, frequent deployments.
Key activities:
- Increase automated test coverage for critical monolith modules (target 60%).
- Implement consumer-driven contract testing (Pact) between monolith and new services.
- Set up automated regression test suites for end-to-end flows.
- Integrate tests into CI/CD pipelines with quality gates.
- Enable blue-green and canary deployments for both monolith and services.
Output: a reliable deployment pipeline that supports rollback and rapid feedback.
5. Extract Catalogue and Search Service (depends on: 3, 4)
Extract the Catalogue and Search service. This is a read-heavy, low-coupling module, making it a good first candidate.
Key activities:
- Create a new Catalogue service with its own datastore (PostgreSQL for product data, Elasticsearch for search).
- Implement data synchronization from the monolith via CDC and events.
- Migrate read APIs for product listing and search to the new service via the gateway.
- Use feature flags to gradually shift traffic, with fallback to the monolith.
- Monitor performance and rollback if issues arise.
Output: an independently deployable Catalogue service serving a portion of traffic.
6. Extract Customer Accounts and Loyalty Service (depends on: 3, 4, 5)
Extract the Customer Accounts and Loyalty service. This service manages profiles, addresses, and loyalty points.
Key activities:
- Create a new Customer service with its own database.
- Synchronize data from the monolith via events (customer created, updated).
- Migrate profile management and loyalty APIs to the new service.
- Keep authentication in the monolith initially to reduce risk.
- Redirect customer API calls to the new service gradually.
Output: an independently deployable Customer service with data ownership.
7. Extract Inventory Service (depends on: 3, 4)
Extract the Inventory service. This service consumes the warehouse file feed directly and maintains real-time inventory.
Key activities:
- Create an Inventory service that reads the warehouse file feed (SFTP) and parses it.
- Publish inventory update events to Kafka.
- Migrate inventory queries from the monolith to the new service.
- Ensure the monolith and other services consume inventory events instead of querying the monolith DB.
Output: an independently deployable Inventory service with real-time updates.
8. Extract Returns Service (depends on: 3, 4, 6)
Extract the Returns service. This module is relatively independent and can be extracted early.
Key activities:
- Create a Returns service with its own database.
- Consume order and customer events to validate returns.
- Migrate returns UI and APIs to the new service.
- Ensure integration with order management for refunds.
Output: an independently deployable Returns service.
9. Peak Season Readiness and Resilience Engineering (depends on: 1)
Prepare for peak seasons and implement resilience engineering. This is critical to avoid downtime during January and July sales.
Key activities:
- Conduct load testing for 12x peak on new services and the monolith.
- Implement circuit breakers, bulkheads, rate limiting, and auto-scaling.
- Define change freeze periods: one month before and during January and July sales.
- Plan migration activities outside freeze windows.
- Run game days for failure scenarios and rollback drills.
Output: a system that can withstand peak loads and a schedule that protects peak seasons.
10. Extract Cart Service (depends on: 3, 4, 7)
Extract the Cart service. The cart is a stateful component that requires careful handling.
Key activities:
- Create a Cart service with its own datastore (e.g., Redis or PostgreSQL) for session and cart items.
- Use the API gateway to route cart operations.
- Synchronize with the monolith via events for product and inventory validation.
- Ensure idempotency and session stickiness.
- Gradually migrate cart traffic using feature flags.
Output: an independently deployable Cart service.
11. Extract Order Management and Checkout Orchestration (depends on: 10, 6, 7, 9)
Extract Order Management and Checkout Orchestration. This is the core transactional flow and requires a saga pattern.
Key activities:
- Create an Order service that orchestrates checkout using the saga pattern.
- Integrate with payment providers, inventory, pricing, and customer services.
- Migrate order placement and management APIs.
- Use events for order status updates.
- Ensure distributed transaction consistency and compensation logic.
Output: an independently deployable Order service handling the checkout flow.
12. Extract Pricing and Promotions Service (depends on: 11)
Extract the Pricing and Promotions service. This is the most complex module with 200k lines of rules.
Key activities:
- Analyze and document the existing pricing rules and country-specific logic.
- Implement a new Pricing service, possibly using a rules engine (e.g., Drools).
- Migrate pricing calculations and promotions to the new service.
- Execute after other services are stable and outside peak seasons.
- Use extensive testing and canary releases.
Output: an independently deployable Pricing service with clear rules.
13. Database Decomposition and Stored Procedure Refactoring (depends on: 3)
Decompose the database and refactor stored procedures. This is a cross-cutting concern that runs alongside service extraction.
Key activities:
- Start with logical separation: create schemas per service and move tables gradually.
- Refactor stored procedures into application code or move them to services.
- Eventually, give each service its own database instance.
- Use CDC and dual-write for data consistency during transition.
- Keep the monolith DB as source of truth until cutover.
Output: a decomposed database with clear data ownership.
14. Reorganize Teams for Independent Deployment (depends on: 1, 2)
Reorganize teams for independent deployment. This step enables long-term autonomy.
Key activities:
- Reorganize teams around services (stream-aligned teams).
- Give each team ownership of its service's repository, CI/CD, and on-call.
- Implement an internal developer platform for self-service deployments.
- Establish service level objectives (SLOs) and error budgets.
Output: autonomous teams that can deploy independently.
15. Post-Migration Optimization and Monolith Decommissioning (depends on: 12)
Optimize after migration and decommission the monolith. This step wraps up the migration.
Key activities:
- After each service extraction, remove dead code from the monolith.
- Gradually reduce the monolith to a smaller core (e.g., back-office).
- Plan eventual decommissioning of monolith components.
- Document learnings and update architecture.
Output: a leaner monolith and a fully service-oriented architecture.
--- PROPOSAL 3 (agent qwen3.8-flash_initial_3, alibaba/qwen3.8-flash) ---
Estimated complexity: high
Success metrics: - **Zero Downtime**: Achieve 100% availability of the e-commerce platform throughout the 12 months, including planned maintenance windows.
- **Deployment Independence**: New services can be deployed independently; no code commit forces a full 30-minute monolith downtime. Time-to-deploy for a new service < 5 minutes.
- **Database Decoupling**: Eliminate cross-service SQL joins. The monolith database write load decreases by 90%.
- **Peak Capacity**: System handles 12x traffic load (approx. 480k orders/day) with < 200ms latency at P95 during load tests.
- **Search Latency**: Product availability reflected in search results within < 30 seconds of inventory update (replacing nightly rebuild).
- **Pricing Stability**: 0% deviation in price calculation results between the new architecture and the legacy 'golden master' characterization tests.
Steps (10):
1. Foundation: Infrastructure, Observability, and Safety Net
Before extracting any service, the team must build the 'operating system' for distributed applications. This step focuses on enabling independent deployment and providing real-time visibility into the legacy monolith. The goal is to create a safety net that makes subsequent refactoring steps low-risk and reversible.
* **CI/CD Pipeline**: Implement a dual-track pipeline. The existing monolith gets a 'speedy' pipeline for hotfixes, while a new pipeline infrastructure is set up (e.g., Kubernetes/ECS) ready for independent service deployment.
* **Observability Suite**: Deploy centralized logging (ELK/Loki), metrics (Prometheus/Grafana), and crucially, **Distributed Tracing** (Jaeger/Zipkin). Even within the monolith, we must map request flows to identify coupling.
* **Service Mesh / API Gateway**: Install an API Gateway (e.g., Kong, Nginx ingress) in front of the monolith. This is the 'strangler fig' entry point. All traffic must flow through here. We will use it to route traffic to new services or fallback to the monolith.
* **Feature Flags**: Integrate a feature management system (e.g., LaunchDarkly, Unleash) to decouple deployment from release. This allows us to deploy code that is inactive and test it behind flags.
2. Domain Analysis and Boundary Definition (Strangler Pattern) (depends on: 1)
You cannot extract a service without knowing the domain. With 2M lines and 'unknown' pricing logic, this step is about mapping the terrain. We aim to identify low-risk, high-cohesion boundaries for the first extractions and mark the 'danger zones' (Pricing) for later.
* **Event Storming**: Run workshops with the five teams to map business flows (e.g., 'Checkout', 'Return') and identify command/event boundaries.
* **Code Hotspot Analysis**: Use static analysis tools (e.g., SonarQube, CodeScene) to find files changed together (logical coupling) and complex methods.
* **Dependency Matrix**: Create a matrix showing which database tables are accessed by which application modules. This is critical for the database refactoring later.
* **Service Extraction Plan**: Finalize the order of extraction. Recommended: **Search/Catalogue** (read-heavy, low transactional consistency risk) or **Inventory** (async, distinct boundary). Avoid 'Pricing' initially due to complexity and 'Checkout' until foundational identity is stable.
3. Data Platform Strategy: Outbox Pattern and CDC (depends on: 2)
The 1.2TB PostgreSQL DB with stored procedures is the 'database of doom' for migration. We must stop using cross-module SQL joins. This step introduces a data change capture layer to allow services to communicate via events rather than DB writes.
* **Database Isolation**: Begin identifying tables exclusive to the chosen first domain (e.g., Catalogue tables). Grant strict read-only access to other modules if possible, or refactor code to remove cross-table joins.
* **Change Data Capture (CDC)**: Deploy a tool (e.g., Debezium or Kafka Connect) to stream PostgreSQL WAL logs to a message broker (Kafka/Pulsar). This creates a stream of data changes that can be consumed by other services.
* **Transaction Outbox**: Refactor the monolith code to use an 'Outbox Pattern' for domain events. Instead of just writing to the DB, it also writes a message to an 'Outbox' table in the same transaction. A relay process moves this to Kafka. This ensures 'at least once' delivery and keeps the monolith's transactional integrity while enabling async communication.
4. Extraction of First Service (The 'Read-Only' Pilot) (depends on: 1, 3)
To learn safely, we extract a 'read-only' service with no transactional complexity. The **Product Catalogue/Search** is the best candidate. It is currently Lucene-based, rebuilt nightly. We will move to real-time indexing to improve product freshness.
* **Build the Catalogue Service**: Create a new microservice that owns the Catalogue database tables. It exposes gRPC/REST endpoints for fetching products.
* **Real-time Sync**: The new service subscribes to the CDC events for product changes (from S3). It updates its internal Lucene/Opensearch index in real-time. This eliminates the nightly rebuild and provides immediate search visibility.
* **Dual Read Path**: The monolith code for 'Search' is modified to check a feature flag. If enabled, it calls the new Catalogue Service; otherwise, it uses the old internal Lucene logic.
* **Shadow Traffic**: Use the API Gateway to duplicate live traffic. Send requests to both the monolith and the new service. Compare the responses. Only when error rates are 0% do we flip the feature flag for production traffic.
5. Extraction of Identity and Customer Accounts (depends on: 4)
Next, we extract the **Customer Account** domain. This serves both the storefront and the mobile app. This is a write-heavy domain, requiring careful transaction handling with the legacy monolith during the transition.
* **Service Implementation**: Implement the 'Customer Service' (JWT generation, profile management, authentication). It owns its own database schema (User, Address).
* **Sync with Legacy**: The service publishes 'UserUpdated' and 'UserCreated' events via Outbox/CDC. The monolith listens to these events to keep its local copy of user data synchronized.
* **Strangler Endpoint**: The API Gateway routes '/api/login', '/api/account' traffic directly to the new service. The monolith stops handling these requests. Front-end applications must be updated to handle the new response format (versioning).
* **Database Decoupling**: Over time, remove read access to the monolith's user table for all other domains, forcing them to use the Identity service.
6. Extraction of Inventory Synchronization (depends on: 5)
Inventory is currently updated every 15 minutes via files. This is a bottleneck. We will extract this into a service that integrates directly with the Warehouse Management System (WMS).
* **Inventory Service**: Build a service that consumes warehouse data feeds (replacing the file drop). It updates a centralized stock level view.
* **Event Publishing**: When stock levels change, publish `StockLevelChanged` events to Kafka.
* **Monolith Integration**: Refactor the Cart/Checkout code in the monolith to listen to these events to maintain a local cached view of inventory or to check stock via an API call rather than a SQL join. This removes the 15-minute latency.
* **Consistency Model**: Since inventory is high-concurrency, design a reservation system (Saga) for this service to prepare for the future extraction of Checkout.
7. The 'Black Box' Strategy for Pricing and Promotions (depends on: 6)
The pricing module (200k lines, unknown rules) cannot be rewritten safely from scratch. We treat it as a 'legacy core'. We will wrap it in a service but keep the internal logic untouched in the monolith initially, or isolate it.
* **Characterization Tests**: Write massive integration tests that record the input/output of the pricing module for all 8 countries and 3 currencies. This creates a 'golden master'.
* **Decouple Dependencies**: Refactor the pricing code to rely only on 'Customer', 'Product', and 'Inventory' data fetched via interfaces, not direct DB calls. This prepares it for extraction.
* **Extract as 'Black Box'**: Wrap the existing pricing logic into a new `Pricing Service`. Move the 200k lines of code into this project. It calls a dedicated read-replica database of the pricing tables. This service does not communicate with others directly but is called by the 'Cart' service.
* **Validation**: Run 'shadow mode' traffic against this new service to ensure it matches the golden master before routing any production traffic.
8. Orchestration Layer: Cart and Checkout (The Saga) (depends on: 7)
Checkout is the highest risk. It requires distributed transaction management. We will implement the Cart as a service and the Checkout process as an orchestrator using Sagas.
* **Cart Service**: Extract cart logic into its own stateless/stateful service (Redis-backed). This decouples the browsing experience from the order processing.
* **Checkout Orchestrator**: Build a new 'Order Service' that does not do the work itself but coordinates the process. When a checkout starts, the Order Service begins a **Saga**.
* **Saga Steps**: 1. Validate Pricing (via Pricing Service), 2. Reserve Inventory (via Inventory Service), 3. Authorize Payment (via Payment Service), 4. Create Order Record. If step 3 fails, step 1/2 must be compensated (rollback).
* **Idempotency**: Ensure all services in the saga accept Idempotency Keys to prevent double-charging or double-stock deduction.
9. Extraction of Payments and Order Management (depends on: 8)
Complete the order lifecycle. Move payment integration and order status tracking out of the monolith.
* **Payment Gateway**: Extract the integration with the 3 providers into a `Payment Service`. This service handles webhooks, refunds, and tokenization (PCI scope reduction).
* **Order Management System (OMS)**: Move the database table `orders` and associated history into a new `Order Service`. It consumes the events generated by the Checkout Saga.
* **Back-office Migration**: The back-office (300 staff) is likely server-rendered. Refactor these screens to consume the new `Order Service` APIs. Remove the back-office's direct SQL access to the orders table. This is crucial for reducing load on the monolith DB.
10. Legacy Cleanup and Peak Season Preparation (depends on: 9)
The monolith should now be a 'hollowed-out' shell (mostly just the legacy pricing rules inside a service or a 'legacy' module). We prepare for the peak sales in Jan/July.
* **Database Downsizing**: Detach the schema ownership. The monolith should ideally only connect to a 'read-only' replica for historical data or a small remnant DB.
* **Performance Tuning**: The new architecture is now the single point of failure. Optimize the message broker (Kafka) and API Gateway for 12x traffic.
* **Chaos Engineering**: Run game-days testing resilience. Kill a service (e.g., Search) and ensure the storefront degrades gracefully (shows empty search results but allows cart access).
* **Final Monolith Decommission**: Identify the remaining monolith code. Delete it. If it's just a 'legacy gateway', replace it with pure API routing. The 'Monolith' label should now refer only to the Pricing Service or similar, not a single deployable unit.
Your answer has these parts:
- "round_summary": two or three sentences on the round as a whole (approaches taken, how different the proposals are).
- "proposals": one entry per proposal, each with "proposal" (its number), "summary" (a very concise summary of what the agent proposes: three or four sentences at most) and "approach" (the angle it takes, in a few words).
[ROUND 1]
[SYSTEM]
You are an expert reviewer of multi-agent planning processes.
Several LLM agents drafted plans for a task, refined them over a number of rounds while seeing each other's proposals, and finally voted for the best one.
Be exhaustive but precise: name concrete steps, ideas and metrics, never generalities. Judge plans by their fitness for the task as stated, their realism, their completeness, the soundness of their order and dependencies, how measurable their success is and how they handle things going wrong.
You are an impartial evaluator, not a chronicler: assess the proposals and the process on their merits, never rationalise what happened or assume that the outcome was right.
After your analysis, answer in the requested structure.
Every text field you write will be read by a busy person, so write for them: short sentences, one idea each, in short paragraphs. Text fields accept Markdown: separate paragraphs with a blank line, use a bullet list when you enumerate things and plain paragraphs when you explain or argue, and bold at most one key phrase per paragraph. A text of more than three sentences must be split into paragraphs; never deliver a single unbroken block of text.
[HUMAN]
Task given to the agents: "A mid-size European fashion retailer runs its e-commerce on a 10-year-old monolith: Java 8 / Spring, about 2 million lines, one PostgreSQL database of 1.2 TB with 350 tables and heavy use of stored procedures and cross-module joins. It serves 8 countries, 3 currencies and 4 languages, with about 40,000 orders a day and peaks of 12x during sales. The monolith contains: the storefront (server-rendered, plus a separate mobile app hitting the same endpoints), catalogue and search (a Lucene index rebuilt nightly), pricing and promotions (the most complex module, 200,000 lines, with country-specific rules nobody fully understands), cart and checkout with three payment providers, order management, inventory synchronised every 15 minutes with the warehouse system via file exchange, customer accounts and loyalty, returns, and a back-office used by 300 staff. Deployments happen every two weeks as a single artefact with a 30-minute maintenance window; test coverage is 25% and mostly unit tests. Five teams of 8 developers, each organised around a business area but all committing to the same repository.
Plan the migration to independently deployable services over 12 months with no feature freeze, no unplanned downtime and the ability to roll back every step, preserving the peak-season capacity (sales in January and July must not be put at risk)."
This is round 1, a refinement round: every agent received ALL the proposals of round 0 and wrote a new plan, improving on them or taking a different approach. By convention, the previous version of proposal N is proposal N of round 0, written by the same model.
PROPOSALS OF ROUND 0 (the previous versions):
--- PROPOSAL 1 (agent claudeHaiku4.5_initial_1, anthropic/claude-haiku-4-5) ---
Estimated complexity: high
Success metrics: - All 8 services independently deployed and running in production with zero unplanned downtime during 12-month migration
- Zero data inconsistencies between service-specific databases (validated by monthly reconciliation)
- January and July peak seasons proceed with no degradation: 480k orders/day processed within 5-second checkout SLA
- Test coverage increased from 25% to 70%+ for all extracted services
- Every service deployment is fully automated; manual rollback procedures tested and <30 minutes to execute
- Order processing latency (cart → confirmation) unchanged or improved: maintained under 5 seconds at peak load
- All 5 teams deploying independently: no cross-team deployment coordination required after cutover
- Pricing/promotions service successfully extracted with all 200k LOC of country-specific rules preserved and validated
- Search latency improved or maintained despite architectural change
- Inventory synchronization with warehouse continues reliably: no missed 15-minute sync cycles
- Back-office operations for 300 staff members unaffected by migration; service aggregation endpoints maintain <500ms latency
- Zero payment processing regressions: all three payment providers functioning, fraud detection active, PCI-DSS compliance maintained
Steps (24):
1. Current State Documentation & Target Architecture
Create a detailed map of the monolith to inform service extraction strategy.
- Audit all modules: storefront, catalogue, search, pricing/promotions, cart, checkout, orders, inventory, customers, loyalty, returns, back-office
- Map dependencies between modules, identifying cross-module calls and data flows
- Model future bounded contexts using Domain-Driven Design
- Create technology inventory (libraries, frameworks, protocols)
- Document interface contracts for each module
- Identify which teams own which modules for organizational alignment
2. Data Dependency Analysis & Dual-Write Strategy (depends on: 1)
Untangle the 1.2TB database to support service independence without blocking progress.
- Map all 350 tables to future service domains
- Identify cross-service joins and stored procedures that span domains
- Design per-service database schemas with minimal denormalization
- Create data versioning framework to support rollback
- Plan dual-write patterns: how old monolith and new services will sync during transition
- Document eventual-consistency requirements and conflict resolution
- Design data migration runbooks with clear rollback steps
3. Test Coverage Audit & Improvement Roadmap (depends on: 1)
Build confidence for service extraction by eliminating test blindness.
- Audit current 25% test coverage by module
- Identify coverage gaps in modules scheduled for early extraction
- Establish target of 70%+ coverage for modules being extracted
- Prioritize integration tests over unit tests given monolith complexity
- Create quality gates: no service extraction below 60% module coverage
- Plan for continuous improvement during extraction phases
4. Peak-Season Window Planning & Risk Framework (depends on: 1)
Protect January and July sales by scheduling extractions during safe windows.
- Map annual peak periods: January sales (peak orders), July sales, plus any promotional events
- Define 4-week freeze windows before/during peaks
- Identify lowest-risk windows in each month for major changes
- Create rollback procedures that execute in <30 minutes
- Establish monitoring escalation for changes made near peak season
- Document communication plan with business teams
5. Observability Foundation Setup
Instrument the system for real-time visibility during migration.
- Deploy centralized logging (ELK, Splunk, or similar)
- Set up metrics collection (Prometheus, Datadog, or similar)
- Implement distributed tracing (Jaeger, Zipkin) for request flows across services
- Create dashboards for: requests/sec, error rates, latency percentiles, database load
- Define SLOs: order processing latency p99, checkout success rate, payment authorization speed
- Set up alerts for SLO violations and anomalies
6. Feature Flags, Containerization & API Gateway
Build the technical foundation for canary deployments and controlled traffic routing.
- Implement feature flag system (LaunchDarkly, custom Spring Boot solution, etc.)
- Containerize monolith and all new services (Docker)
- Set up container orchestration (Kubernetes or similar) with service templates
- Deploy API gateway (Kong, AWS ALB) with routing rules
- Implement service-to-service authentication (mTLS, JWT)
- Configure rate limiting and circuit breakers at gateway
7. Deployment Pipeline & Automated Rollback (depends on: 6)
Enable safe, automated deployments with reliable rollback capability.
- Implement CI/CD pipeline with automated testing gates
- Set up blue-green deployment: run old and new versions in parallel, switch traffic atomically
- Build canary deployment capability: route 5%→10%→50%→100% of traffic gradually
- Automate rollback: trigger on error rate threshold, latency spike, or manual command
- Create deployment runbooks for each service
- All deployments must be independent; monolith keeps 2-week cycle until fully extracted
8. Test Coverage Improvement to 70%+ (depends on: 3)
Close test gaps before extracting services to reduce rollback risk.
- Implement integration tests for key flows: order creation, payment processing, inventory updates
- Add contract tests between modules to catch breaking changes
- Use mutation testing to verify test quality
- Target 70%+ coverage for: pricing module, payment module, order management
- Establish automated quality gates: coverage <70% blocks extraction of that service
- Include tests for peak-load scenarios (40k→480k orders)
9. Search/Catalogue Service Extraction & Validation (depends on: 7, 8, 3)
Extract the first service: search is read-heavy, isolated, and low-risk.
- Extract catalogue and search indexing logic from monolith
- Build as independent Spring Boot service with own codebase/deployment
- Create new database schema for catalogue (subset of 350 tables)
- Implement dual-write: monolith writes to both old Lucene index and new service
- Implement canary routing: API gateway sends 10% of search requests to new service, monitor latency and correctness
- Validate results match between old and new service (checksums on result sets)
- Gradually increase traffic: 10%→25%→50%→100%
- Keep dual-write active for 2 weeks post-cutover for rollback safety
10. Event Bus & Service Mesh Infrastructure (depends on: 9)
Build async communication layer required for multi-service coordination.
- Deploy message broker (Kafka recommended for ordering guarantees and peak load of 40k/sec)
- Define domain events: OrderPlaced, PaymentAuthorized, InventoryReserved, etc.
- Implement event schema versioning and compatibility
- Set up service discovery (Consul, Kubernetes DNS)
- Implement distributed configuration management
- Create event publishing library for services to use
- Document saga patterns for multi-step workflows
- Test message broker under peak load (480k messages/day)
11. Inventory Service Extraction & Warehouse Sync (depends on: 10)
Extract inventory as second service: well-bounded, drives warehouse sync complexity.
- Extract inventory logic and reservation system
- Build inventory service with own database schema
- Implement dual-write from monolith to both old and new inventory data
- Preserve existing 15-minute warehouse file exchange, but now via service
- Create inventory events: ReservationCreated, ReleaseRequested
- Implement canary rollout: gradual traffic shift like search service
- Test warehouse sync under peak load
- Validate inventory consistency across monolith and new service before full cutover
12. Customer/Loyalty Service Extraction & Auth Refactoring (depends on: 10)
Extract customer accounts and loyalty: enables independent scaling of auth layer.
- Extract customer account and loyalty program logic
- Build customer service with own database schema
- Separate authentication from monolith: implement API for token validation
- Support multi-tenant loyalty rules (8 countries, country-specific points rules)
- Implement canary rollout with real customer sessions
- Create backwards-compatible customer APIs
- Test account operations at peak concurrency (concurrent logins, loyalty point updates)
- Plan for session management: ensure distributed sessions work across services
13. Saga Pattern Library & Order Orchestration Framework (depends on: 10)
Build the framework for managing distributed transactions across services.
- Implement saga pattern library: choreography-based (event-driven) and orchestration-based patterns
- Support compensating transactions: if payment fails, return inventory reservation
- Handle timeouts and retries with exponential backoff
- Implement idempotency keys to prevent duplicate charges on retries
- Test saga execution under peak load and network failures
- Document patterns for: order placement saga, payment saga, return saga
- Create distributed tracing for saga flows
14. Pricing/Promotions Service Extraction (Phase 1: Extract As-Is) (depends on: 13)
Begin extraction of most complex module (200k LOC) without initial refactoring.
- Extract pricing engine as-is with minimal refactoring to reduce initial risk
- Preserve all country-specific rules and business logic
- Build service boundary: accept pricing requests, return prices/promotions
- Create feature tests that document all 200k LOC behavior
- Map all promotion types to test scenarios
- Test with real country/currency/language combinations
- Implement as service behind same interface initially
- Prepare for Phase 2 refactoring once stable in production
15. Pricing/Promotions Service Refinement (Phase 2: Rules Refactoring) (depends on: 14)
Gradually improve pricing service maintainability without breaking production.
- Document the 200k LOC of complex rules in machine-readable format
- Refactor rules engine into composable components
- Build DSL for country-specific promotion rules
- Decompose monolithic rule evaluation into smaller decision trees
- Use feature flags to A/B test refactored rules vs old implementation
- Optimize performance: reduce calculation time for promotions at checkout
- Validate that refactored logic matches original behavior across all countries
16. Payment Service Extraction & Security Hardening (depends on: 13)
Extract payment processing with extreme rigor given PCI/regulatory requirements.
- Separate payment logic from checkout: payment validation, three-provider integration
- Build payment service with encrypted credential storage, no raw card data in logs
- Implement fraud detection integration and decline handling
- Audit for PCI-DSS compliance: minimal data exposure, encrypted transport
- Implement E2E testing for all three payment provider scenarios
- Load test payment service: 500+ payments/sec at peak
- Implement idempotent payment requests: prevent double-charging on failures
- Create detailed rollback procedures: how to fall back to direct monolith payment handling
17. Order Service Extraction & Event Stream (depends on: 13, 16)
Extract order management: central service coordinating multiple workflows.
- Extract order creation, status tracking, and management logic
- Build order service with event stream: OrderCreated, PaymentAuthorized, InventoryReserved, OrderConfirmed
- Support order querying by all 5 teams (inventory, fulfillment, customer service, etc.)
- Implement order event sourcing for audit trail and replay capability
- Create order state machine: validate state transitions
- Test concurrent order processing at peak load (40k orders/day)
18. Checkout Service Composition via Saga (depends on: 17)
Compose checkout from independent payment, inventory, and order services using sagas.
- Build checkout service that orchestrates: cart validation → pricing calculation → inventory reservation → payment authorization → order creation
- Use saga pattern: if payment fails, release inventory reservation automatically
- Implement distributed transaction semantics: all-or-nothing guarantee
- Support three payment providers transparently
- Test all failure scenarios: payment declines, inventory unavailable, warehouse system down
- Implement timeout handling: what happens if inventory service is slow at peak
- Validate checkout latency remains <5 seconds at peak load
19. Back-Office Integration with Service APIs (depends on: 18)
Update back-office (used by 300 staff) to coordinate across all services.
- Create service aggregation endpoints: orders endpoint calls order service + payment service + inventory service
- Update back-office UI to call new service APIs instead of monolith
- Implement service discovery: handle service availability transparently
- Create caching layer: reduce latency for frequently accessed data
- Test with 300 concurrent staff users
- Implement search across all orders/customers via service APIs
- Add retry logic and timeouts to handle service failures gracefully
20. Storefront & Mobile App Refactoring (depends on: 19)
Update client applications to use new service architecture transparently.
- Update server-rendered storefront templates to call service APIs
- Update mobile app endpoints (already separate, now points to services via gateway)
- Implement client-side caching: reduce latency impact of distributed calls
- Maintain backwards compatibility: old clients must still work
- Update API versioning: enable service changes without breaking clients
- Implement request tracing: correlate user requests across services
- Test storefront and mobile under peak load scenario (480k orders/day)
21. Legacy Database Deprecation & Data Migration (depends on: 20)
Safely decommission the monolith database once all services are independent.
- Verify all data has been migrated to service-specific databases
- Maintain 2-week read-only access to old database for emergency queries
- Archive old database snapshots (regulatory requirement for order history)
- Update backup/recovery procedures: now per-service instead of monolith
- Verify no remaining cross-service joins depend on monolith schema
- Document data mapping for future reference
- Decommission old database infrastructure
22. Load Testing & Performance Optimization (depends on: 21)
Validate new architecture meets production capacity requirements.
- Simulate peak load scenario: 480k orders/day (40k baseline × 12)
- Test across 8 countries, 3 currencies, 4 languages simultaneously
- Identify bottlenecks: service latency, database query performance, message broker throughput
- Optimize hot paths: pricing calculations, search queries, payment processing
- Test cache effectiveness: Lucene search response times, pricing cache hit rates
- Validate database connection pools don't exhaust under peak load
- Create load testing environment: realistic data, all 5 teams' concurrent usage
23. Documentation & Knowledge Transfer (depends on: 22)
Codify migration experience and new architecture for long-term success.
- Document final service boundaries: APIs, responsibilities, data ownership
- Create operational runbooks: how to deploy each service, how to handle common failures
- Record architecture decision log: why services were split this way
- Document data consistency model: eventual consistency patterns used
- Create troubleshooting guides: common issues and resolutions
- Train each team on their service and API contracts with other services
- Record key decisions and trade-offs (e.g., why search is separate from catalogue, why pricing is monolithic within its service)
24. Production Stabilization & 30-Day Monitoring (depends on: 23)
Establish stable operation and prove architecture meets requirements.
- Run 30-day monitoring period observing: error rates, latency, resource utilization
- Establish performance baselines: P99 latency per service, throughput, error rates
- Document SLO achievements: order processing speed, payment success rate, search latency
- Create incident playbooks based on observed issues
- Validate peak-load handling (Jan/July sales go normally through new architecture)
- Establish team on-call procedures for service alerts
- Plan for service scaling: autoscaling policies, capacity planning
- Complete full rollback verification: ensure rollback to monolith is always possible
--- PROPOSAL 2 (agent deepseek-flash_initial_2, deepseek/deepseek-flash) ---
Estimated complexity: high
Success metrics: - 100% of planned service extractions completed within 12 months.
- Zero unplanned downtime during January and July peak sales.
- All new services independently deployable with <5 minute lead time.
- 100% of deployments rollback-able within 5 minutes.
- 80% of traffic served by new services by end of 12 months.
- Test coverage increased to 60% for critical modules.
- Deployment frequency increased from bi-weekly to daily.
- Mean time to recovery (MTTR) < 30 minutes.
- Change failure rate < 15%.
- All stored procedures refactored or migrated to services.
- Database decomposed into 5+ independent databases.
- Peak load capacity sustained at 12x with <1% error rate.
Steps (15):
1. Mobilize Program and Define Target Architecture
Launch the migration program and define the target architecture. This step sets the foundation for all subsequent work.
Key activities:
- Establish a steering committee with business, architecture, and operations representatives.
- Conduct domain-driven design workshops to identify bounded contexts and service candidates.
- Define the target architecture: API gateway, service mesh, event-driven integration, and data ownership per service.
- Prioritize service extraction based on business value, risk, and coupling.
- Create architecture decision records (ADRs) and a service roadmap.
Output: a shared vision and prioritized backlog for the migration.
2. Build Platform Foundation for Independent Deployments (depends on: 1)
Build the platform foundation required for independent deployments. This includes infrastructure, tooling, and golden paths.
Key activities:
- Provision a Kubernetes cluster with namespaces for each service.
- Set up CI/CD pipelines per service using GitLab CI or ArgoCD.
- Deploy an API gateway (e.g., Kong) and service mesh (e.g., Istio) for traffic management.
- Implement observability: centralized logging (ELK), metrics (Prometheus/Grafana), and tracing (Jaeger).
- Set up secrets management (Vault) and configuration management.
- Create golden path templates for new services to reduce boilerplate.
Output: a production-ready platform where teams can deploy services independently.
3. Implement Strangler Fig Facade and Monolith Instrumentation (depends on: 2)
Implement the strangler fig facade and instrument the monolith. This allows incremental migration without disrupting users.
Key activities:
- Deploy the API gateway to route requests to the monolith or new services based on path or header.
- Modify the monolith to expose REST APIs for key domains (e.g., catalogue, customer).
- Implement the transactional outbox pattern to publish domain events from the monolith.
- Set up change data capture (CDC) from the monolith PostgreSQL to Kafka using Debezium.
- Introduce feature flags for routing and canary releases.
- Ensure all changes are backward compatible and can be rolled back.
Output: a facade that enables gradual traffic shifting and a data pipeline for synchronization.
4. Establish Continuous Delivery and Test Automation (depends on: 1)
Establish continuous delivery and test automation to support safe, frequent deployments.
Key activities:
- Increase automated test coverage for critical monolith modules (target 60%).
- Implement consumer-driven contract testing (Pact) between monolith and new services.
- Set up automated regression test suites for end-to-end flows.
- Integrate tests into CI/CD pipelines with quality gates.
- Enable blue-green and canary deployments for both monolith and services.
Output: a reliable deployment pipeline that supports rollback and rapid feedback.
5. Extract Catalogue and Search Service (depends on: 3, 4)
Extract the Catalogue and Search service. This is a read-heavy, low-coupling module, making it a good first candidate.
Key activities:
- Create a new Catalogue service with its own datastore (PostgreSQL for product data, Elasticsearch for search).
- Implement data synchronization from the monolith via CDC and events.
- Migrate read APIs for product listing and search to the new service via the gateway.
- Use feature flags to gradually shift traffic, with fallback to the monolith.
- Monitor performance and rollback if issues arise.
Output: an independently deployable Catalogue service serving a portion of traffic.
6. Extract Customer Accounts and Loyalty Service (depends on: 3, 4, 5)
Extract the Customer Accounts and Loyalty service. This service manages profiles, addresses, and loyalty points.
Key activities:
- Create a new Customer service with its own database.
- Synchronize data from the monolith via events (customer created, updated).
- Migrate profile management and loyalty APIs to the new service.
- Keep authentication in the monolith initially to reduce risk.
- Redirect customer API calls to the new service gradually.
Output: an independently deployable Customer service with data ownership.
7. Extract Inventory Service (depends on: 3, 4)
Extract the Inventory service. This service consumes the warehouse file feed directly and maintains real-time inventory.
Key activities:
- Create an Inventory service that reads the warehouse file feed (SFTP) and parses it.
- Publish inventory update events to Kafka.
- Migrate inventory queries from the monolith to the new service.
- Ensure the monolith and other services consume inventory events instead of querying the monolith DB.
Output: an independently deployable Inventory service with real-time updates.
8. Extract Returns Service (depends on: 3, 4, 6)
Extract the Returns service. This module is relatively independent and can be extracted early.
Key activities:
- Create a Returns service with its own database.
- Consume order and customer events to validate returns.
- Migrate returns UI and APIs to the new service.
- Ensure integration with order management for refunds.
Output: an independently deployable Returns service.
9. Peak Season Readiness and Resilience Engineering (depends on: 1)
Prepare for peak seasons and implement resilience engineering. This is critical to avoid downtime during January and July sales.
Key activities:
- Conduct load testing for 12x peak on new services and the monolith.
- Implement circuit breakers, bulkheads, rate limiting, and auto-scaling.
- Define change freeze periods: one month before and during January and July sales.
- Plan migration activities outside freeze windows.
- Run game days for failure scenarios and rollback drills.
Output: a system that can withstand peak loads and a schedule that protects peak seasons.
10. Extract Cart Service (depends on: 3, 4, 7)
Extract the Cart service. The cart is a stateful component that requires careful handling.
Key activities:
- Create a Cart service with its own datastore (e.g., Redis or PostgreSQL) for session and cart items.
- Use the API gateway to route cart operations.
- Synchronize with the monolith via events for product and inventory validation.
- Ensure idempotency and session stickiness.
- Gradually migrate cart traffic using feature flags.
Output: an independently deployable Cart service.
11. Extract Order Management and Checkout Orchestration (depends on: 10, 6, 7, 9)
Extract Order Management and Checkout Orchestration. This is the core transactional flow and requires a saga pattern.
Key activities:
- Create an Order service that orchestrates checkout using the saga pattern.
- Integrate with payment providers, inventory, pricing, and customer services.
- Migrate order placement and management APIs.
- Use events for order status updates.
- Ensure distributed transaction consistency and compensation logic.
Output: an independently deployable Order service handling the checkout flow.
12. Extract Pricing and Promotions Service (depends on: 11)
Extract the Pricing and Promotions service. This is the most complex module with 200k lines of rules.
Key activities:
- Analyze and document the existing pricing rules and country-specific logic.
- Implement a new Pricing service, possibly using a rules engine (e.g., Drools).
- Migrate pricing calculations and promotions to the new service.
- Execute after other services are stable and outside peak seasons.
- Use extensive testing and canary releases.
Output: an independently deployable Pricing service with clear rules.
13. Database Decomposition and Stored Procedure Refactoring (depends on: 3)
Decompose the database and refactor stored procedures. This is a cross-cutting concern that runs alongside service extraction.
Key activities:
- Start with logical separation: create schemas per service and move tables gradually.
- Refactor stored procedures into application code or move them to services.
- Eventually, give each service its own database instance.
- Use CDC and dual-write for data consistency during transition.
- Keep the monolith DB as source of truth until cutover.
Output: a decomposed database with clear data ownership.
14. Reorganize Teams for Independent Deployment (depends on: 1, 2)
Reorganize teams for independent deployment. This step enables long-term autonomy.
Key activities:
- Reorganize teams around services (stream-aligned teams).
- Give each team ownership of its service's repository, CI/CD, and on-call.
- Implement an internal developer platform for self-service deployments.
- Establish service level objectives (SLOs) and error budgets.
Output: autonomous teams that can deploy independently.
15. Post-Migration Optimization and Monolith Decommissioning (depends on: 12)
Optimize after migration and decommission the monolith. This step wraps up the migration.
Key activities:
- After each service extraction, remove dead code from the monolith.
- Gradually reduce the monolith to a smaller core (e.g., back-office).
- Plan eventual decommissioning of monolith components.
- Document learnings and update architecture.
Output: a leaner monolith and a fully service-oriented architecture.
--- PROPOSAL 3 (agent qwen3.8-flash_initial_3, alibaba/qwen3.8-flash) ---
Estimated complexity: high
Success metrics: - **Zero Downtime**: Achieve 100% availability of the e-commerce platform throughout the 12 months, including planned maintenance windows.
- **Deployment Independence**: New services can be deployed independently; no code commit forces a full 30-minute monolith downtime. Time-to-deploy for a new service < 5 minutes.
- **Database Decoupling**: Eliminate cross-service SQL joins. The monolith database write load decreases by 90%.
- **Peak Capacity**: System handles 12x traffic load (approx. 480k orders/day) with < 200ms latency at P95 during load tests.
- **Search Latency**: Product availability reflected in search results within < 30 seconds of inventory update (replacing nightly rebuild).
- **Pricing Stability**: 0% deviation in price calculation results between the new architecture and the legacy 'golden master' characterization tests.
Steps (10):
1. Foundation: Infrastructure, Observability, and Safety Net
Before extracting any service, the team must build the 'operating system' for distributed applications. This step focuses on enabling independent deployment and providing real-time visibility into the legacy monolith. The goal is to create a safety net that makes subsequent refactoring steps low-risk and reversible.
* **CI/CD Pipeline**: Implement a dual-track pipeline. The existing monolith gets a 'speedy' pipeline for hotfixes, while a new pipeline infrastructure is set up (e.g., Kubernetes/ECS) ready for independent service deployment.
* **Observability Suite**: Deploy centralized logging (ELK/Loki), metrics (Prometheus/Grafana), and crucially, **Distributed Tracing** (Jaeger/Zipkin). Even within the monolith, we must map request flows to identify coupling.
* **Service Mesh / API Gateway**: Install an API Gateway (e.g., Kong, Nginx ingress) in front of the monolith. This is the 'strangler fig' entry point. All traffic must flow through here. We will use it to route traffic to new services or fallback to the monolith.
* **Feature Flags**: Integrate a feature management system (e.g., LaunchDarkly, Unleash) to decouple deployment from release. This allows us to deploy code that is inactive and test it behind flags.
2. Domain Analysis and Boundary Definition (Strangler Pattern) (depends on: 1)
You cannot extract a service without knowing the domain. With 2M lines and 'unknown' pricing logic, this step is about mapping the terrain. We aim to identify low-risk, high-cohesion boundaries for the first extractions and mark the 'danger zones' (Pricing) for later.
* **Event Storming**: Run workshops with the five teams to map business flows (e.g., 'Checkout', 'Return') and identify command/event boundaries.
* **Code Hotspot Analysis**: Use static analysis tools (e.g., SonarQube, CodeScene) to find files changed together (logical coupling) and complex methods.
* **Dependency Matrix**: Create a matrix showing which database tables are accessed by which application modules. This is critical for the database refactoring later.
* **Service Extraction Plan**: Finalize the order of extraction. Recommended: **Search/Catalogue** (read-heavy, low transactional consistency risk) or **Inventory** (async, distinct boundary). Avoid 'Pricing' initially due to complexity and 'Checkout' until foundational identity is stable.
3. Data Platform Strategy: Outbox Pattern and CDC (depends on: 2)
The 1.2TB PostgreSQL DB with stored procedures is the 'database of doom' for migration. We must stop using cross-module SQL joins. This step introduces a data change capture layer to allow services to communicate via events rather than DB writes.
* **Database Isolation**: Begin identifying tables exclusive to the chosen first domain (e.g., Catalogue tables). Grant strict read-only access to other modules if possible, or refactor code to remove cross-table joins.
* **Change Data Capture (CDC)**: Deploy a tool (e.g., Debezium or Kafka Connect) to stream PostgreSQL WAL logs to a message broker (Kafka/Pulsar). This creates a stream of data changes that can be consumed by other services.
* **Transaction Outbox**: Refactor the monolith code to use an 'Outbox Pattern' for domain events. Instead of just writing to the DB, it also writes a message to an 'Outbox' table in the same transaction. A relay process moves this to Kafka. This ensures 'at least once' delivery and keeps the monolith's transactional integrity while enabling async communication.
4. Extraction of First Service (The 'Read-Only' Pilot) (depends on: 1, 3)
To learn safely, we extract a 'read-only' service with no transactional complexity. The **Product Catalogue/Search** is the best candidate. It is currently Lucene-based, rebuilt nightly. We will move to real-time indexing to improve product freshness.
* **Build the Catalogue Service**: Create a new microservice that owns the Catalogue database tables. It exposes gRPC/REST endpoints for fetching products.
* **Real-time Sync**: The new service subscribes to the CDC events for product changes (from S3). It updates its internal Lucene/Opensearch index in real-time. This eliminates the nightly rebuild and provides immediate search visibility.
* **Dual Read Path**: The monolith code for 'Search' is modified to check a feature flag. If enabled, it calls the new Catalogue Service; otherwise, it uses the old internal Lucene logic.
* **Shadow Traffic**: Use the API Gateway to duplicate live traffic. Send requests to both the monolith and the new service. Compare the responses. Only when error rates are 0% do we flip the feature flag for production traffic.
5. Extraction of Identity and Customer Accounts (depends on: 4)
Next, we extract the **Customer Account** domain. This serves both the storefront and the mobile app. This is a write-heavy domain, requiring careful transaction handling with the legacy monolith during the transition.
* **Service Implementation**: Implement the 'Customer Service' (JWT generation, profile management, authentication). It owns its own database schema (User, Address).
* **Sync with Legacy**: The service publishes 'UserUpdated' and 'UserCreated' events via Outbox/CDC. The monolith listens to these events to keep its local copy of user data synchronized.
* **Strangler Endpoint**: The API Gateway routes '/api/login', '/api/account' traffic directly to the new service. The monolith stops handling these requests. Front-end applications must be updated to handle the new response format (versioning).
* **Database Decoupling**: Over time, remove read access to the monolith's user table for all other domains, forcing them to use the Identity service.
6. Extraction of Inventory Synchronization (depends on: 5)
Inventory is currently updated every 15 minutes via files. This is a bottleneck. We will extract this into a service that integrates directly with the Warehouse Management System (WMS).
* **Inventory Service**: Build a service that consumes warehouse data feeds (replacing the file drop). It updates a centralized stock level view.
* **Event Publishing**: When stock levels change, publish `StockLevelChanged` events to Kafka.
* **Monolith Integration**: Refactor the Cart/Checkout code in the monolith to listen to these events to maintain a local cached view of inventory or to check stock via an API call rather than a SQL join. This removes the 15-minute latency.
* **Consistency Model**: Since inventory is high-concurrency, design a reservation system (Saga) for this service to prepare for the future extraction of Checkout.
7. The 'Black Box' Strategy for Pricing and Promotions (depends on: 6)
The pricing module (200k lines, unknown rules) cannot be rewritten safely from scratch. We treat it as a 'legacy core'. We will wrap it in a service but keep the internal logic untouched in the monolith initially, or isolate it.
* **Characterization Tests**: Write massive integration tests that record the input/output of the pricing module for all 8 countries and 3 currencies. This creates a 'golden master'.
* **Decouple Dependencies**: Refactor the pricing code to rely only on 'Customer', 'Product', and 'Inventory' data fetched via interfaces, not direct DB calls. This prepares it for extraction.
* **Extract as 'Black Box'**: Wrap the existing pricing logic into a new `Pricing Service`. Move the 200k lines of code into this project. It calls a dedicated read-replica database of the pricing tables. This service does not communicate with others directly but is called by the 'Cart' service.
* **Validation**: Run 'shadow mode' traffic against this new service to ensure it matches the golden master before routing any production traffic.
8. Orchestration Layer: Cart and Checkout (The Saga) (depends on: 7)
Checkout is the highest risk. It requires distributed transaction management. We will implement the Cart as a service and the Checkout process as an orchestrator using Sagas.
* **Cart Service**: Extract cart logic into its own stateless/stateful service (Redis-backed). This decouples the browsing experience from the order processing.
* **Checkout Orchestrator**: Build a new 'Order Service' that does not do the work itself but coordinates the process. When a checkout starts, the Order Service begins a **Saga**.
* **Saga Steps**: 1. Validate Pricing (via Pricing Service), 2. Reserve Inventory (via Inventory Service), 3. Authorize Payment (via Payment Service), 4. Create Order Record. If step 3 fails, step 1/2 must be compensated (rollback).
* **Idempotency**: Ensure all services in the saga accept Idempotency Keys to prevent double-charging or double-stock deduction.
9. Extraction of Payments and Order Management (depends on: 8)
Complete the order lifecycle. Move payment integration and order status tracking out of the monolith.
* **Payment Gateway**: Extract the integration with the 3 providers into a `Payment Service`. This service handles webhooks, refunds, and tokenization (PCI scope reduction).
* **Order Management System (OMS)**: Move the database table `orders` and associated history into a new `Order Service`. It consumes the events generated by the Checkout Saga.
* **Back-office Migration**: The back-office (300 staff) is likely server-rendered. Refactor these screens to consume the new `Order Service` APIs. Remove the back-office's direct SQL access to the orders table. This is crucial for reducing load on the monolith DB.
10. Legacy Cleanup and Peak Season Preparation (depends on: 9)
The monolith should now be a 'hollowed-out' shell (mostly just the legacy pricing rules inside a service or a 'legacy' module). We prepare for the peak sales in Jan/July.
* **Database Downsizing**: Detach the schema ownership. The monolith should ideally only connect to a 'read-only' replica for historical data or a small remnant DB.
* **Performance Tuning**: The new architecture is now the single point of failure. Optimize the message broker (Kafka) and API Gateway for 12x traffic.
* **Chaos Engineering**: Run game-days testing resilience. Kill a service (e.g., Search) and ensure the storefront degrades gracefully (shows empty search results but allows cart access).
* **Final Monolith Decommission**: Identify the remaining monolith code. Delete it. If it's just a 'legacy gateway', replace it with pure API routing. The 'Monolith' label should now refer only to the Pricing Service or similar, not a single deployable unit.
Step-level differences computed by the tool:
Proposal 1 vs the previous-round proposal it resembles most (claudeHaiku4.5_initial_1): 5 steps kept, added ['Platform Foundation: Kubernetes, CI/CD, and Observability', 'Strangler Pattern Setup: API Gateway, Feature Flags, and Service Mesh', 'Domain Analysis and Service Boundary Definition via Event Storming', 'Peak Season Protection Framework and Change Freeze Calendar', 'Pricing Module Characterization: Black Box Baseline and Test Suite', 'Change Data Capture and Event-Driven Data Sync Infrastructure', 'Saga Pattern Framework and Distributed Transaction Orchestration', 'Orders Service Extraction: Orchestrator for Checkout and Fulfillment', 'Cart Service Extraction: Stateful Session Management', 'Pricing Service Extraction: Black Box Wrapping and Golden Master Validation', 'Returns Service Extraction and Order Lifecycle Completion', 'Back-Office Service Aggregation and Staff User Experience', 'Load Testing and Peak Capacity Validation Across Full System', 'Team Reorganization and Independent Deployment Readiness', 'Monolith Decommissioning and Legacy Code Cleanup'], removed ['Current State Documentation & Target Architecture', 'Data Dependency Analysis & Dual-Write Strategy', 'Test Coverage Audit & Improvement Roadmap', 'Peak-Season Window Planning & Risk Framework', 'Observability Foundation Setup', 'Feature Flags, Containerization & API Gateway', 'Deployment Pipeline & Automated Rollback', 'Event Bus & Service Mesh Infrastructure', 'Saga Pattern Library & Order Orchestration Framework', 'Pricing/Promotions Service Extraction (Phase 1: Extract As-Is)', 'Pricing/Promotions Service Refinement (Phase 2: Rules Refactoring)', 'Order Service Extraction & Event Stream', 'Checkout Service Composition via Saga', 'Back-Office Integration with Service APIs', 'Storefront & Mobile App Refactoring', 'Legacy Database Deprecation & Data Migration', 'Load Testing & Performance Optimization', 'Documentation & Knowledge Transfer', 'Production Stabilization & 30-Day Monitoring']
Proposal 2 vs the previous-round proposal it resembles most (deepseek-flash_initial_2): 4 steps kept, added ['Program setup, peak-aware calendar, rollback charter and scope ladder', 'Executable architecture map, table ownership and boundary enforcement', 'Delivery platform: per-module pipelines, gateway, feature flags, environments', 'Observability, business SLOs, error budgets and the automated rollback controller', 'Split the deployment unit and retire the 30-minute maintenance window', 'Seam-level verification: golden master, contracts, shadow diffing, reconciliation', 'Data platform: schema ownership, join elimination, CDC, outbox, four-stage cutover playbook', 'Extract Returns as the first write-path and own-database proof', 'Extract Inventory and replace the 15-minute warehouse file exchange', 'Extract Payment under a stricter regime than anything else', 'Extract Order Management with an explicit state machine', 'Compose Checkout from independent services using a saga', 'Migrate back-office, storefront and mobile clients off the monolith database', 'Decommission the monolith core and harden for the second peak'], removed ['Mobilize Program and Define Target Architecture', 'Build Platform Foundation for Independent Deployments', 'Implement Strangler Fig Facade and Monolith Instrumentation', 'Establish Continuous Delivery and Test Automation', 'Extract Inventory Service', 'Extract Returns Service', 'Peak Season Readiness and Resilience Engineering', 'Extract Order Management and Checkout Orchestration', 'Database Decomposition and Stored Procedure Refactoring', 'Reorganize Teams for Independent Deployment', 'Post-Migration Optimization and Monolith Decommissioning']
Proposal 3 vs the previous-round proposal it resembles most (deepseek-flash_initial_2): 2 steps kept, added ['Mobilization and Strategic Freeze Planning', 'Target Architecture and Domain Boundaries', 'Core Infrastructure and Observability Foundation', "Test Harness: 'Golden Master' Characterization", 'Extraction 2: Customer Identity and Profile', "Database Decoupling: The 'Anti-Corruption' Layer", 'Extraction 3: Inventory and Fulfillment Interface', 'Extraction 5: Checkout Orchestrator (Saga Pattern)', 'Final Monolith Decomposition and Clean-up', 'Peak Season Stress Test and Handover'], removed ['Mobilize Program and Define Target Architecture', 'Build Platform Foundation for Independent Deployments', 'Implement Strangler Fig Facade and Monolith Instrumentation', 'Establish Continuous Delivery and Test Automation', 'Extract Customer Accounts and Loyalty Service', 'Extract Inventory Service', 'Extract Returns Service', 'Peak Season Readiness and Resilience Engineering', 'Extract Cart Service', 'Extract Order Management and Checkout Orchestration', 'Database Decomposition and Stored Procedure Refactoring', 'Reorganize Teams for Independent Deployment', 'Post-Migration Optimization and Monolith Decommissioning']
Origin of the steps of the new proposals, matched by title by the tool (evidence for "taken"; ideas can also travel without a matching title):
Proposal 1: 6 of its 20 steps match its own previous version, 12 are new; step 19 resembles step 14 of proposal 2; step 3 resembles step 2 of proposal 3
Proposal 2: 4 of its 18 steps match its own previous version, 14 are new
Proposal 3: 3 of its 12 steps match its own previous version, 7 are new; steps 5, 9 resemble steps 5, 12 of proposal 2
PROPOSALS OF ROUND 1 (to assess):
--- PROPOSAL 1 (agent claudeHaiku4.5_refine_1, anthropic/claude-haiku-4-5) ---
Estimated complexity: high
Success metrics: - Zero unplanned downtime during 12-month migration; all maintenance windows scheduled and communicated; zero production incidents caused by migration
- Peak seasons (January and July sales) proceed with zero degradation: 480k orders/day processed with p95 checkout latency < 5 seconds, payment authorization < 2 seconds, zero payment processing failures
- All eight services independently deployable: no code commits force monolith downtime; new service deployment < 5 minutes; deployment frequency increases from bi-weekly (monolith) to daily (services) where applicable
- Test coverage increased from 25% to 70%+ for all extracted services (Search, Inventory, Customer, Cart, Orders, Payments, Returns); characterization test suite for Pricing passes 100% before service extraction
- Every service deployment is rollback-able in < 30 minutes: documented procedures tested monthly; rollback automated where possible
- Data consistency validated: monthly reconciliation between service databases and monolith shows zero inconsistencies; dual-write period completes successfully (2 weeks per service)
- Order processing SLA maintained: cart → confirmation latency unchanged or improved; maintained under 5 seconds at peak load (480k orders/day)
- All five teams deploying independently by month 12: no cross-team deployment coordination required; each team owns service, deployment pipeline, on-call rotation
- Search latency improved or maintained: product availability reflected in search results within < 1 minute of inventory update (vs. previous nightly rebuild), baseline latency unchanged
- Inventory synchronization preserved: no missed 15-minute warehouse sync cycles during migration; 100% of daily inventory updates processed
- Back-office operations unaffected: 300 staff members seamlessly using new service APIs; service aggregation endpoints maintain < 500ms p95 latency
- Payment processing: zero regressions with all three payment providers; fraud detection remains active; PCI-DSS compliance maintained; idempotency prevents duplicate charges
- Event-driven architecture validated: Kafka message broker handles 480k messages/day at peak; no message loss or ordering violations
- Rollback capability proven: every step validated to be reversible; no permanent cutover without 30-day validation period and green light from peak season calendar
Steps (20):
1. Platform Foundation: Kubernetes, CI/CD, and Observability
Establish the technical foundation for independent service deployment and operation before touching the monolith architecture.
- Provision Kubernetes cluster with dev/staging/prod namespaces, or equivalent managed cloud platform (ECS/App Engine)
- Deploy centralized logging (ELK or Loki), metrics (Prometheus/Grafana), and distributed tracing (Jaeger)
- Implement CI/CD pipelines for independent service deployments (GitHub Actions/GitLab CI/ArgoCD)
- Set up secrets management (Vault) and configuration management (Consul/Spring Cloud Config)
- Create observability dashboards for: order throughput, latency percentiles (P50/P95/P99), error rates, database load
- Define SLOs and alerting: order processing latency p99 < 5 seconds, checkout success rate > 99.5%, payment auth speed < 2 seconds
2. Strangler Pattern Setup: API Gateway, Feature Flags, and Service Mesh (depends on: 1)
Deploy the infrastructure layer that enables gradual traffic migration from monolith to services without downtime.
- Deploy API gateway (Kong or AWS ALB) in front of monolith; all traffic routes through gateway
- Implement feature flag system (LaunchDarkly or Unleash) to decouple deployment from traffic routing
- Set up service mesh (Istio or Linkerd) for inter-service communication, mTLS, and circuit breakers
- Containerize monolith as-is (Docker) so it can run alongside new services
- Instrument monolith with event publishing capability: add transactional outbox table for domain events
- Create blast radius containment: rate limiting, bulkheads, and timeouts at gateway level
3. Domain Analysis and Service Boundary Definition via Event Storming (depends on: 2)
Map the monolith's business domains and dependencies to identify safe extraction sequence and service boundaries.
- Run event storming workshops with all five teams; map customer journeys (Browse → Cart → Checkout → Order → Fulfillment → Returns)
- Create dependency matrix: which tables, stored procedures, and methods are accessed by each domain
- Use code hotspot analysis (SonarQube, CodeScene) to find logical coupling and identify decoupling opportunities
- Define service extraction sequence based on coupling and business risk: prioritize read-heavy (Search), well-bounded (Inventory), and identity (Customer) over complex (Pricing, Checkout)
- Document all cross-module joins; mark which ones must be eliminated vs. which can tolerate eventual consistency
- Identify stored procedures that span multiple domains; plan refactoring or replication strategy
4. Peak Season Protection Framework and Change Freeze Calendar (depends on: 3)
Establish hard boundaries to protect January and July sales from destabilizing changes.
- Map annual peak periods: January sales (peak revenue), July sales, plus promotional events
- Define 6-week freeze windows: 4 weeks before + 2 weeks during each peak season; no major extractions or refactors during freeze
- Identify lowest-risk windows in each month for incremental changes (hotfixes, small extractions, data migrations only)
- Create rollback runbooks for every step: how to revert traffic routing, database changes, and service deployments in < 30 minutes
- Establish incident escalation and communication plan: business owners notified of any changes near peak season
- Plan load testing outside freeze windows: validate 12x capacity (480k orders/day) for each service before peak season
5. Pricing Module Characterization: Black Box Baseline and Test Suite (depends on: 3)
Thoroughly document the 200k LOC pricing engine behavior before any extraction attempt, eliminating unknown risk.
- Analyze and document all pricing rules: country-specific logic, currency handling, promotional rules, edge cases
- Create comprehensive characterization test suite: record input/output for all 8 countries × 3 currencies × major promotional scenarios
- This test suite becomes the 'golden master': any new pricing service must match 100% of outputs
- Build test data set covering: normal pricing, discounts, bulk pricing, regional pricing, multi-currency edge cases, seasonal promotions
- Document all dependencies: which customer attributes, product attributes, inventory levels, and time-based factors affect pricing
- Establish CI gate: pricing service extraction cannot proceed until characterization tests pass 100%
6. Test Coverage Improvement: Target 70% for Extract-Candidate Modules (depends on: 3)
Increase test confidence for modules scheduled for early extraction; reduce rollback risk from test blindness.
- Audit current test coverage by module; identify gaps in: Search, Catalogue, Inventory, Cart, Customer
- Implement integration tests for critical flows: order creation, payment processing, inventory updates, customer account creation
- Add contract tests (Pact) between modules to catch API breaking changes early
- Use mutation testing to verify test quality: tests must catch injected bugs
- Target 70%+ coverage for Search, Inventory, Customer, Cart, Payments modules
- Establish automated quality gates: no service extraction if module coverage < 60%; no production deployment if < 70%
- Create load test suites for peak scenarios: simulate 40k→480k order escalation for each module
7. Change Data Capture and Event-Driven Data Sync Infrastructure (depends on: 2, 5)
Build the plumbing to eliminate cross-module database joins and enable eventual consistency between services.
- Deploy CDC tool (Debezium with Kafka/Pulsar) to stream PostgreSQL WAL changes to message broker
- Refactor monolith to use transactional outbox pattern: all domain events written atomically in same transaction as business data
- Create event schema versioning: events must be backwards/forwards compatible as services evolve
- Implement dual-write mechanism: during transition, write to both monolith database and new service database
- Set up event relay: monolith publishes events (OrderPlaced, PaymentAuthorized, InventoryReserved) to Kafka
- Define eventual consistency model: which operations can tolerate delayed propagation vs. which require immediate consistency
8. Search and Catalogue Service Extraction: Read-Heavy Pilot Service (depends on: 6, 7)
Extract the first service: read-heavy, low transactional risk, validates the entire strangler fig pattern.
- Build new Catalogue and Search service: REST API for product lookup, search, and filtering
- Create new database schema (PostgreSQL): product data, categories, attributes; use Elasticsearch/OpenSearch for real-time search indexing
- Subscribe to CDC events from monolith: ProductUpdated events trigger real-time search index refresh (eliminates nightly Lucene rebuild, improves freshness to < 1 minute)
- Implement dual-read path: feature flag controls whether requests hit monolith Lucene or new Search service
- Use API gateway shadow traffic: send requests to both old and new service; compare responses; alert on differences
- Gradually shift traffic: 10% → 25% → 50% → 100% using feature flags and canary deployments
- Maintain dual-write for 2 weeks post-cutover to verify correctness; then deprecate monolith search code
9. Inventory Service Extraction: Real-Time Warehouse Synchronization (depends on: 7, 8)
Extract inventory as second service: async boundary, directly integrates with warehouse system, eliminates 15-minute sync latency.
- Build Inventory service: consumes warehouse file feed (SFTP/API) directly instead of monolith polling
- Create inventory database schema: stock levels, reservations, holds per product per location
- Publish inventory events: StockLevelChanged, ReservationCreated, ReservationReleased to Kafka
- Implement reservation system (prepare for saga pattern): inventory holds items during checkout, releases on order confirmation or timeout
- Dual-write monolith inventory data during transition: maintain consistency between old and new
- Test warehouse sync at peak load: ensure 15-minute sync windows do not slip under 480k daily orders
- Validate that all cart and checkout code calls inventory service via API (or consumes events) rather than direct SQL join
- Gradual traffic shift: test with non-critical inventory queries first, then critical paths
10. Customer and Loyalty Service Extraction: Identity Decoupling (depends on: 9)
Extract customer accounts and loyalty programs: enables independent auth scaling and multi-tenant loyalty rules.
- Build Customer service: JWT token generation, profile management, address management, identity verification
- Create customer database schema (separate from monolith): User, Address, Profile; replicate to read-only cache where needed
- Implement loyalty points service: handles country-specific loyalty rules (8 countries, different point accrual rates)
- Sync customer data via events: monolith publishes CustomerCreated, CustomerUpdated, CustomerDeleted to Kafka
- API gateway routes: /api/login, /api/profile, /api/loyalty to new Customer service; monolith drops these endpoints
- Ensure backwards compatibility: versioned API responses so old mobile app clients still work
- Test at peak concurrency: concurrent logins, loyalty point updates under 480k orders/day load
- Implement session management: distributed sessions (Redis-backed) so users stay logged in during monolith↔service transitions
11. Saga Pattern Framework and Distributed Transaction Orchestration (depends on: 7)
Implement the orchestration layer required for multi-service transactions before extracting payment and order services.
- Build saga pattern library: support both choreography (event-driven) and orchestration (centralized coordinator) patterns
- Implement compensating transactions: if payment fails during checkout, inventory reservation and pricing calc must roll back
- Add idempotency framework: all services accept idempotency-key headers; prevent duplicate charges, double-deductions
- Handle timeouts and retries: exponential backoff, circuit breakers, manual intervention for stuck sagas
- Create saga log: record saga execution with state transitions for auditing, debugging, and replay
- Test saga execution under peak load and network failures: simulate payment provider latency, inventory service timeouts
- Document saga flows: checkout saga (price → reserve inventory → authorize payment → create order), return saga, refund saga
- Implement distributed tracing: each saga step is traced end-to-end for observability
12. Payment Service Extraction: PCI-Scoped and Secure (depends on: 11)
Extract payment processing with extreme security rigor: handles card data, three payment providers, regulatory compliance.
- Build Payment service: integration with all three payment providers (tokenization, authorization, capture, refund)
- Implement PCI-DSS compliance: no raw card data in logs, encrypted transport, minimal data exposure in monolith
- Handle payment declines and fraud: integrate fraud detection, implement retry logic for transient failures
- Create idempotent payment requests: prevent double-charging if client retries or network fails mid-request
- Implement webhook handling: payment providers notify service of async events (captures, chargebacks, refunds)
- Design rollback procedure: if new service fails catastrophically, fall back to direct monolith payment handling (via feature flag)
- Load test: 500+ payments/sec at peak (baseline 40k orders/day → 480k orders/day = ~550 payments/sec)
- Test all three provider scenarios: happy path, declines, timeouts, chargebacks
13. Orders Service Extraction: Orchestrator for Checkout and Fulfillment (depends on: 12)
Extract order management: central service coordinating checkout saga and order lifecycle across all services.
- Build Order service: order creation, status tracking, order querying API for all business users (inventory, fulfillment, customer service teams)
- Implement checkout orchestrator: accepts cart (items, customer, delivery address) → triggers saga → creates order record on success
- Integrate with Payment service (authorize payment), Inventory service (reserve stock), Pricing service (calculate total), Customer service (loyalty points)
- Implement order state machine: validate state transitions (Pending → Confirmed → Shipped → Delivered), prevent invalid transitions
- Create order event stream: OrderCreated, PaymentAuthorized, InventoryReserved, OrderConfirmed, OrderShipped for other services to consume
- Use event sourcing: maintain immutable log of all order state changes for audit trail and replay capability
- Test concurrent order processing at peak load: 40k→480k orders/day; ensure no race conditions, duplicate orders, or lost transactions
- API design: query orders by customer ID, order ID, SKU, date range; sorting and filtering for back-office use
14. Cart Service Extraction: Stateful Session Management (depends on: 10)
Extract shopping cart as stateful service: decouples browsing/cart operations from order processing, independent scaling.
- Build Cart service: add/remove items, update quantities, persist session state, apply coupons/discounts
- Implement cart storage: Redis for session-backed stateless carts, or PostgreSQL with session affinity for persistent carts
- Integration with services: calls Catalogue service (product availability), Inventory service (stock check), Pricing service (cart totals)
- API design: cart operations (add/remove/view), subtotals with pricing breakdowns, coupon application
- Implement session stickiness: API gateway routes same user to same Cart service instance (or share Redis state)
- Test at peak concurrency: concurrent cart updates from same user (one browser tab → mobile app → browser again)
- Ensure idempotency: adding same item twice returns same cart state, no duplicates
- Gradual traffic shift: test with non-critical users first, then ramp up
15. Pricing Service Extraction: Black Box Wrapping and Golden Master Validation (depends on: 5, 13)
Extract pricing logic as black box service using characterization tests to ensure 100% correctness preservation.
- Move 200k LOC pricing logic into dedicated Pricing service with own codebase
- Service exposes API: accepts product IDs, customer attributes, location, time, inventory levels → returns price, applicable promotions, currency
- Use dedicated read-replica database with pricing tables only (no cross-joins to other domains)
- Run shadow mode traffic: send live pricing requests to both old monolith and new service; compare outputs; alert on any divergence
- Validation gate: pricing service must match characterization test suite 100% for all 8 countries, 3 currencies, all tested scenarios
- Feature flag control: gradually shift production traffic once shadow mode validates correctness
- Document decision: this service remains a black box (we don't refactor internal logic); future teams can safely extend without fear
- Plan Phase 2 refactoring separately: after service is stable in production, optionally decompose into rules engine (Drools) in future quarter
16. Returns Service Extraction and Order Lifecycle Completion (depends on: 13, 15)
Extract returns handling: completes order lifecycle, depends on Orders and Pricing services being stable.
- Build Returns service: process return requests, validate return eligibility, calculate refunds (using Pricing service), manage return shipping
- Integrate with Orders service: fetch order data, verify items purchased
- Integrate with Inventory service: return items to stock after confirmation
- Integrate with Payment service: process refunds back to original payment method
- API design: create return request, track return status, generate return shipping labels
- Implement return state machine: Requested → Approved → Shipped → Received → Refunded
- Consumer integration: back-office staff (or customer self-service) calls Returns service APIs instead of monolith
- Test return flows at peak load: validate no inventory/refund race conditions
17. Back-Office Service Aggregation and Staff User Experience (depends on: 13, 16)
Update back-office (300 staff) to consume new service APIs; eliminate monolith direct database access.
- Create service aggregation endpoints: orders endpoint calls Order + Payment + Inventory + Shipping services; returns endpoint calls Returns service
- Implement API gateway service discovery: back-office transparently calls services even if they move/scale
- Add caching layer: frequently accessed data (customer profiles, order lists) cached with TTL to reduce service latency
- Implement timeouts and graceful degradation: if one service is slow, show cached data or partial results
- Refactor back-office UI: replace monolith SQL queries with REST API calls
- Test with 300 concurrent staff users: search across orders/customers, filtering by date/status, bulk actions
- Implement distributed tracing: back-office requests are traced across all services for debugging
- Add retry logic: transient failures (network blips) automatically retry; permanent failures show user-friendly errors
18. Load Testing and Peak Capacity Validation Across Full System (depends on: 17)
Validate new distributed architecture handles peak load (480k orders/day) without degradation; stress test before peak seasons.
- Simulate realistic peak load: 480k orders/day (12x baseline), 8 countries, 3 currencies, 4 languages simultaneously
- Test sequence: base load → ramp to 480k → sustain for 30 minutes → spike to 1.5x peak → graceful degradation
- Measure latencies: checkout flow (cart → confirmation) p95 < 5 seconds, payment authorization < 2 seconds, search < 1 second
- Monitor service-level metrics: requests/sec, error rates, database query times, message broker throughput, cache hit rates
- Identify and optimize bottlenecks: pricing calculations, search queries, payment provider round-trip time, inventory reservations
- Test database connection pools: ensure no exhaustion or deadlocks under peak load
- Validate message broker (Kafka): 480k messages/day throughput, latency, durability
- Create realistic user behavior: product browsing → search → add to cart → checkout flows, not just load
- Fail-over testing: kill one service (e.g., Search); verify system degrades gracefully, no cascading failures
- Load test outside freeze windows; complete before January/July peak seasons
19. Team Reorganization and Independent Deployment Readiness (depends on: 18)
Reorganize teams around services to enable independent deployments and long-term operational autonomy.
- Reorganize five teams: from business-function-based (Pricing team, Fulfillment team) to stream-aligned (Search Service team, Orders Service team)
- Assign service ownership: each team owns their service's codebase, CI/CD pipeline, database schema, on-call rotation, SLOs
- Implement internal developer platform (IDP): golden path templates, self-service deployments, secrets rotation, observability dashboards
- Establish SLOs per service: error budget, latency targets, availability targets
- Create cross-team API contracts: service teams sign off on API changes; breaking changes trigger communication plan
- Set up inter-service communication: API versioning, deprecation periods, backward compatibility requirements
- Plan on-call: each team on-call for their service; pager rotation, incident response training
- Document service dependencies: which services call which; upstream/downstream impact analysis
20. Monolith Decommissioning and Legacy Code Cleanup (depends on: 19)
Safely retire monolith code once all services are stable and production-proven.
- Audit monolith codebase: identify dead code (Search, Catalogue, Inventory, Customer, Orders, Payments, Cart, Returns logic)
- Delete extracted service code from monolith; remove dual-write logic once service has proven stable (30+ days in production)
- Gradually reduce monolith database: archive or migrate old tables, remove cross-module stored procedures
- Plan monolith decommissioning: if monolith becomes shell (mostly unused), decide: keep as fallback or shut down completely
- Maintain 90-day read-only archive of monolith database for emergency historical queries and regulatory retention
- Update backup/recovery procedures: shift from single monolith snapshot to per-service snapshots
- Document architectural decisions: why services were split this way, what problems were solved, what trade-offs were made
- Create incident playbooks: common failure modes, resolution steps, escalation paths
- Close out migration project: update runbooks, retire temporary monitoring, establish steady-state operational procedures
- Celebrate: migration complete, new architecture proven at peak load, five teams deploying independently
Note on proposal 2: Proposal 2 provides solid platform foundations and clear sequencing, but underestimates the pricing risk and extracts checkout before foundational services stabilize.
Adopted: Step 2 (Platform Foundation) adopted: explicit Kubernetes, CI/CD, and observability setup reduces risk of independent deployments
Adopted: CDC/Debezium strategy (Step 13) adopted: event-driven data sync is cleaner than pure dual-write
Adopted: Service mesh setup adopted: explicit mention of Istio for mTLS and circuit breakers strengthens security
Adopted: Team reorganization aspect adopted: moving from business-function to stream-aligned teams is essential for long-term independence
Rejected: Orders service extraction (Step 11) happens before Payments (Step 16) in Proposal 2, but Orders depends on Payments working correctly; the sequence should be Payments first, then Orders as orchestrator
Rejected: Pricing extraction (Step 12) is too late and lacks risk mitigation: 200k LOC complex rules need characterization test baseline before any extraction attempt; Proposal 2 has no explicit golden master validation
Rejected: Only 15 steps is too coarse; Proposal 2 conflates multiple concerns (e.g., 'Post-Migration Optimization') that deserve explicit steps; testing, peak season protection, and validation deserve dedicated steps
Note on proposal 1: Proposal 1 is the most comprehensive with excellent peak-season protection and dual-write rigor, but the 24-step dependency chain creates unnecessary critical-path serialization.
Adopted: Peak-season protection (Step 4 in Proposal 1) adopted wholesale: 6-week freeze windows, 4 weeks before + 2 weeks during peaks, plus rollback runbooks < 30 minutes
Adopted: Test coverage roadmap adopted: systematic audit of current coverage, identify gaps, target 70% for extract candidates, quality gates that block extraction below 60%
Adopted: Dual-write strategy adopted: explicit step for managing consistency between monolith and new services during transition, 2-week validation period post-cutover
Adopted: Pricing phase 1/2 approach adopted: extract as-is first (black box), then optionally refactor rules engine later once stable (though Proposal 3's characterization test baseline is better)
Adopted: Saga pattern library adopted: explicit support for compensating transactions, idempotency, timeouts, and saga logging
Adopted: Load testing strategy adopted: multiple validation points, peak scenarios, chaos engineering game days
Rejected: 24-step sequence is overly granular and serialized; steps 9-20 could be parallelized more aggressively (Search extraction should not wait for Pricing characterization—they are independent)
Rejected: Test Coverage Improvement (Step 8 in Proposal 1) happens after Deployment Pipeline (Step 7), but test quality is a prerequisite for safe canary deployments; should be earlier
Rejected: Service extraction sequencing (Steps 9-15) follows a valid order but lacks explicit emphasis on read-heavy services first; Proposal 1 extracts Search late (Step 9) when it should be first to validate strangler pattern
Rejected: Pricing characterization is implicit in Step 14 ('Create feature tests that document all 200k LOC behavior') but not explicit; Proposal 3's black box approach is clearer and more rigorous about this critical risk
Note on proposal 3: Proposal 3 has excellent strategic insights on pricing risk (black box, characterization tests) and smart sequencing, but is too compressed—10 steps lack operational detail on rollback, dual-write, and peak season protection.
Adopted: Pricing black box strategy adopted: wrap existing 200k LOC logic as-is into a service; use characterization tests (golden master) for validation; shadow mode traffic for correctness verification before production traffic shift
Adopted: Real-time search indexing adopted: move from nightly Lucene rebuild to real-time Elasticsearch/OpenSearch; subscribe to CDC events for instant product freshness (< 1 minute vs. nightly)
Adopted: Event storming workshops adopted: explicit domain analysis step (Step 2 in Proposal 3) before architecture decisions
Adopted: Characterization test emphasis adopted: Proposal 3 correctly identifies this as critical risk mitigation for pricing, making it explicit and foundational
Adopted: Service mesh and observability foundation adopted: Proposal 3 emphasizes these early (Step 1)
Rejected: Only 10 steps lacks operational granularity: rollback procedures, peak season freeze windows, test coverage improvement, and data migration runbooks are underspecified or missing
Rejected: Peak season protection mentioned only in final step (Step 10) but should be early and explicit; Proposal 3 risks scheduling extractions during peak windows if planning happens late
Rejected: Returns service not explicitly extracted (Step 8 in Proposal 3 is vague); returns touches Orders, Inventory, and Payments and deserves its own step with clear dependencies and validation
Rejected: Dual-write and CDC strategy (Step 3 in Proposal 3) lacks detail on how monolith and services stay consistent; transactional outbox pattern deserves explicit treatment, not bundled with database isolation
--- PROPOSAL 2 (agent deepseek-flash_refine_2, deepseek/deepseek-flash) ---
Estimated complexity: high
Success metrics: - Independent deployability: 100% of releases to extracted services require no coordination with another team and no monolith release, demonstrated for at least 6 services by month 9.
- Independent deployability precedes extraction: at least 4 of the 5 teams release their own artefacts without being separate services by month 5.
- The 30-minute maintenance window is retired by month 6; no release after that date requires a planned outage.
- Deployment lead time from merge to production for a single service is 30 minutes or less, and each team releases at least 3 times per week by month 6.
- Zero unplanned downtime attributable to the migration across the 12 months; platform availability of 99.95% or better inside each peak window.
- Both January and July peaks pass with no migration-caused incident: 12x baseline load sustained, checkout p99 under 5 seconds, error rate under 0.5%, no queue backlog beyond 5 minutes.
- 100% of migration increments that reach production have a rollback demonstrated in a game day and executable in under 30 minutes.
- Hourly data reconciliation shows under 0.001% discrepancy on row counts and checksums per module, with zero unexplained business-invariant violations.
- Cross-module database joins and cross-module writes originating in application code are zero for every module at the moment it is extracted, enforced by database roles and CI checks rather than by review.
- Pricing parity: 100% agreement with the golden master on a corpus of at least 1,000,000 historical requests across all 8 countries, 3 currencies and 4 languages, both before and after cutover.
- Stored procedures touching more than one module's tables: zero for every extracted module.
- Search freshness improves from a nightly rebuild to under 30 seconds between a product change and its visibility in search results.
- Warehouse inventory freshness improves from 15 minutes to under 2 minutes end to end.
- 100% of public APIs of extracted services have golden-master or consumer-driven contract coverage; line coverage is tracked only for newly written service code, where it reaches 80%.
- The peak-readiness gate is passed with published evidence six weeks before both peaks, covering 100% of its defined checks.
- Scope ladder rungs 1–6 are complete within 12 months, or the program stops at a rung boundary in a documented, coherent, peak-safe state.
Steps (18):
1. Program setup, peak-aware calendar, rollback charter and scope ladder
Turns the brief's constraints into an operating rhythm that everything later obeys. The binding constraint in this objective is the calendar, not the technology, so the calendar is decided first.
- Run a two-week inception to baseline the current state: build time, deployment lead time, change failure rate, MTTR, MTTR, per-module change frequency, database load profile. Progress must be measurable, not asserted.
- Declare hard freezes from 1 December to 15 January and 1 June to 15 July. During a freeze only rollback-enabling and hardening changes are allowed.
- Confirm the two open delivery windows of the year (roughly February–May and August–November) and accept in writing that only these windows carry migration increments.
- Set the soak rule: no change on the checkout path lands within four weeks of a freeze; anything that would violate it is deferred to the next window.
- Define the peak-readiness gate that runs six weeks before each peak: 12x load test, capacity headroom check, rollback rehearsal, error-budget review. The gate is pass/fail and its evidence is published.
- Write the rollback charter: every increment ships an expand/contract database change, a feature-flag kill switch, and a rehearsal recorded in a game day. No go-live without a rehearsed rollback.
- Publish the scope ladder: a ranked list where rungs 1–6 deliver the core objective and rungs 7+ are optional. Slippage means stopping at a rung boundary, never mid-increment.
- Set the capacity budget at 40–50% of the five teams' capacity for migration alongside normal feature work, and staff the ladder to fit that budget rather than to fill the year.
- Create a migration enablement squad of six engineers drawn on rotation from the five teams. It owns the platform, the shared cuts and the risky shared data work.
2. Executable architecture map, table ownership and boundary enforcement (depends on: 1)
Produces an architecture map that the build itself enforces. Five teams committing to one repository will silently re-couple anything that is separated and not policed, so enforcement is part of the map, not a later step.
- Instrument the monolith with distributed tracing and let it run four weeks. Real call paths beat static imports for finding true coupling.
- Build a table-to-module and query-to-module map by parsing every SQL statement, ORM mapping and stored procedure in the codebase, cross-checked against the database's own query logs.
- Score each candidate service on four axes: coupling, transactional risk, change frequency and peak-path criticality. This ranking, not intuition, drives the extraction order.
- Assign every one of the 350 tables to exactly one owning module. Tables nobody can own are declared contested and scheduled into the data work of S7.
- Add ArchUnit rules to CI that fail the build on any new cross-module Java dependency, with existing violations frozen into a baseline file that may only shrink.
- Add a SQL linter to CI that fails on cross-module joins and cross-module writes, with the same shrinking baseline.
- Publish the target service list, the owning team per service, and the reasoning as architecture decision records.
- Hold a mid-program review at month six to re-rank the scope ladder using what the map actually showed. This is the one planned re-planning point of the program.
3. Delivery platform: per-module pipelines, gateway, feature flags, environments (depends on: 1, 2)
Builds the delivery and traffic machinery that makes every later step reversible. No module is extracted until its team can deploy, flag and route on its own.
- Extend the platform foundation on Kubernetes (or the existing container platform if one exists) with one namespace per service, quotas and autoscaling policies sized for a 12x peak.
- Put an API gateway in front of the monolith as the strangler entry point. Storefront, mobile and back-office traffic all flow through it from day one, even while it routes everything to the monolith.
- Give every module its own CI/CD pipeline and its own environment. The monolith keeps its current pipeline for hotfixes until S5 replaces it.
- Deploy a feature-flag service and require every new call path to be flag-guarded. Flags are the primary rollback instrument for the whole program.
- Introduce secrets management and per-environment configuration so changing behaviour never requires a monolith redeploy.
- Define golden-path templates for a new service: build, pipeline, observability, health checks, flag integration, database migration tool. Extraction must not start from a blank page.
- Reserve two permanent environments: a full-size production-like soak environment and a load-test environment capable of generating 12x traffic against production-shaped data.
4. Observability, business SLOs, error budgets and the automated rollback controller (depends on: 3)
Makes the system observable enough that a canary is judged automatically and reverted without a human guessing. This is the prerequisite for the rollback promise made in every later step.
- Deploy centralized logging, metrics and distributed tracing, with trace correlation working across the gateway, the monolith and every new service from the start.
- Instrument the monolith's blind spots: query latency by module, connection-pool saturation, Lucene rebuild duration, warehouse file-exchange lag.
- Define SLOs on business outcomes, not infrastructure: checkout success rate, order confirmation p99, search latency, payment authorisation rate, price computation latency, warehouse sync freshness.
- Attach an error budget to each SLO and write the policy: when a service burns budget, its rollout stops automatically and its flags revert. No negotiation during a peak.
- Build the rollback controller: on error-rate or latency divergence beyond threshold during a canary, the gateway shifts traffic back and flags are disabled without human action.
- Create per-service dashboards a tired engineer can read at 03:00, plus one program dashboard showing progress against the scope ladder.
5. Split the deployment unit and retire the 30-minute maintenance window (depends on: 2, 3)
Delivers the objective's headline — independently deployable units — before any process separation, by splitting the build and the release train while the code still runs together. This is the cheapest large win available and it removes the maintenance window.
- Split the single artefact into one build per owning module with a shared parent, so a module can be built, tested and released on its own.
- Allow modules to be released as separate artefacts on the existing runtime first. Independent deployability is a build and release property long before it is a topology property.
- Retire the two-week coordinated release train. Each team gets its own pipeline, cadence and on-call rota, with the gateway and schema compatibility as the contract between teams.
- Adopt expand/contract database migrations so schema and code changes no longer have to ship together.
- Replace the maintenance window with blue-green deployment on two identical stacks, traffic switched at the gateway and rollback performed by switching back.
- Measure and publish the result: deployment lead time, deployment frequency per team, and the share of releases that needed no coordination with another team.
6. Seam-level verification: golden master, contracts, shadow diffing, reconciliation (depends on: 2, 3)
Replaces the impossible goal of blanket test coverage with verification exactly where the cut will be made. A two-million-line monolith cannot reach 70% coverage in a year; a service boundary can be verified to a very high standard in weeks.
- Build a characterization harness that records real production requests and replays them against the monolith, capturing full responses as a golden master. This is the safety net for every extraction.
- Require every extracted service to pass the golden master on its public API before it takes live traffic, producing a diff report rather than a pass/fail.
- Use consumer-driven contract tests between the monolith and each new service, and between services, so a change on one side breaks a build instead of production.
- Run shadow traffic: mirror live requests to the new service, compare responses field by field, and gate the traffic ramp on the divergence rate.
- Build per-module data reconciliation as a first-class test: row counts, checksums and business invariants compared on a schedule, with an owner and an alert threshold.
- Add synthetic canary transactions that execute a real checkout, return and search every few minutes and alert on functional regression before customers notice.
- Explicitly do not pursue blanket line coverage of the monolith. Track coverage only for newly written service code, where the target is 80%.
7. Data platform: schema ownership, join elimination, CDC, outbox, four-stage cutover playbook (depends on: 2, 3, 6)
The hardest part of the program and the part most plans under-specify. It does not depend on service extraction, so it starts in month one and runs in parallel with everything else.
- Enforce ownership inside the database itself: one PostgreSQL role per module, able to write only its own schema and to read others only through defined views. Cross-schema writes are rejected by the database, not by convention.
- Inventory every stored procedure, attribute it to one module, and either move it into that module's code or leave it as a module-private function. After a module is extracted, no stored procedure may touch two modules' tables.
- Eliminate cross-module joins one at a time, replacing each with an API call, an event-fed materialized read model or a duplicated read-only projection. Track the count per module and drive it to zero before that module is cut.
- Stand up change data capture with Debezium reading the PostgreSQL WAL into Kafka. This publishes monolith domain events with no application change, the lowest-risk start available.
- Add a transactional outbox for new services so their events and their state changes commit together.
- Adopt one reusable four-stage cutover playbook per module and apply it identically every time. Stage A: the service owns its schema logically, reads from CDC into its own store, and serves shadow traffic only. Stage B: reads cut over, the monolith stays system of record. Stage C: writes cut over, and the monolith's tables become read-only replicas fed by reverse CDC from the service. Stage D: old tables and dead code are dropped only after a full peak or four clean weeks, whichever is longer.
- Make stage C genuinely reversible: because the sync direction can be flipped, rolling back a write cutover is a configuration change plus a reconciliation pass, not a data restore.
- Build the reconciliation service now so every later cutover has an objective consistency check with thresholds and owners.
- Schedule the 1.2 TB storage migration as background work: new services start on the existing cluster with their own schemas, and physical split happens only once a module is stable.
8. Extract Catalog and Search (depends on: 5, 6, 7)
First extraction, chosen because it is read-heavy, mostly isolated and carries no transactional risk. It also pays for itself: replacing the nightly Lucene rebuild with real-time indexing is a visible business win that buys political cover for the harder cuts.
- Create a Catalog service owning product, category and media tables plus its own search index.
- Feed it from CDC so product and price changes appear in search within seconds instead of after a nightly rebuild.
- Route through the gateway behind a flag and ramp 1% → 5% → 25% → 50% → 100%, with the rollback controller able to revert to the monolith's internal Lucene path at any point.
- Run shadow traffic and compare result sets before any live traffic, then keep the old index warm for two weeks after full cutover.
- Verify the mobile app, which hits the same endpoints, inside the same ramp; its behaviour is part of the go/no-go.
- Land this cut in an open delivery window and let it soak at least four weeks before the freeze.
9. Extract Returns as the first write-path and own-database proof (depends on: 5, 6, 7)
Second extraction and the first that owns writes and a database. Returns is chosen because it is off the peak-critical path, has modest coupling, and exercises the full four-stage playbook at low stakes.
- Build the Returns service with its own schema, consuming order and customer events rather than joining their tables.
- Run the playbook end to end: shadow reads, read cutover, then write cutover with reverse CDC keeping the monolith's tables current.
- Prove the rollback path in a game day before write cutover, including a reconciliation pass and a re-run of the golden master.
- Keep the back-office returns screens on the monolith for now, so staff workflow is untouched by this step.
- Record every friction point and correct the playbook. The real output of this step is a proven, reusable procedure, not just one service.
10. Extract Inventory and replace the 15-minute warehouse file exchange (depends on: 5, 6, 7)
Removes one of the sharpest coupling points in the system and unblocks the checkout work. Inventory is extracted in parallel with the other early cuts because it couples the monolith to an external warehouse process rather than to other modules.
- Build the Inventory service to ingest the warehouse feed directly and publish stock-level events.
- Preserve the existing file-based interface for the first weeks, running the new ingest in parallel with the legacy feed and reconciling hourly until they agree.
- Keep the monolith's inventory tables as a projection fed by events, so cart and checkout keep working unchanged during the cut.
- Design reservation semantics now — reserve, confirm, release, with expiry — even though checkout is not yet extracted. The API is needed later and is cheap to get right here.
- Load-test inventory ingest at 12x, because the warehouse feed schedule and the sales peaks do not always coincide.
- Cut over reads first, then writes, with the rollback controller able to restore the file feed as the source of truth.
11. Extract Customer Accounts and Loyalty, with a conservative auth strategy (depends on: 5, 6, 7, 9)
Extracts customer accounts and loyalty, including the authentication decision. Auth is the step that most often derails e-commerce migrations, so the auth path is deliberately moved last and guarded hardest.
- Build the Customer service owning profile, address and loyalty tables, with country-specific loyalty rules expressed as data where possible and as code where not.
- Keep authentication in the monolith for the first phase. Move token issuance only once customer data is stable, and never within four weeks of a freeze.
- Introduce distributed session handling and a token-validation API so services can verify identity without querying the monolith database.
- Cut over reads, then writes, with reverse CDC, validating against the golden master across all 8 countries and 4 languages.
- Verify the mobile app's session behaviour explicitly, since it holds long-lived sessions the storefront does not.
- Move loyalty point accrual and redemption last, because a loyalty error is a customer-visible financial error, not a technical incident.
12. Extract Cart (depends on: 8, 10, 11)
Extracts the cart, which is stateful and sits directly in front of checkout. It is done before pricing and checkout because both need a stable cart boundary to call.
- Build the Cart service on Redis for session and line-item state, validating products and inventory through service calls rather than database joins.
- Make every cart operation idempotent, because a retried add or remove during a peak must not duplicate a line item.
- Keep the cart tables in the monolith as a read-only projection fed by events, for rollback and for the not-yet-migrated back-office screens.
- Ramp traffic while monitoring cart abandonment rate as the business metric, since cart latency shows up as lost revenue rather than as errors.
- Exercise anonymous and authenticated carts separately; they follow different paths and fail in different ways.
- Land this cut in an open window with a full four-week soak before the freeze.
13. Extract Pricing and Promotions as an unchanged black box (depends on: 5, 6, 7)
Extracts the 200,000-line pricing module without rewriting it. The rules are not understood by anyone, so they are wrapped and characterized rather than reverse-engineered. Rule decomposition, documentation and a DSL are explicitly out of scope for these twelve months.
- Build a golden master corpus from at least a million real historical pricing requests and their recorded outputs, covering all 8 countries, 3 currencies and 4 languages, plus every promotion type that can be discovered.
- Refactor only the module's dependencies: pricing must obtain customer, product and inventory data through interfaces rather than direct database access, so it can be lifted out.
- Move the pricing code into its own service unchanged, owning its tables after cutover, and expose a single decision API.
- Run it in shadow mode for at least four weeks against live traffic, comparing every computed price with the monolith. Any divergence blocks the ramp.
- Cut over behind a flag with per-country ramps, since a pricing error is a financial and legal exposure rather than a technical incident.
- Keep the in-monolith evaluator available and warm as the rollback path for at least one full peak after cutover.
- State in writing that rule decomposition is deferred to a follow-up program, so it does not creep back into this one.
14. Extract Payment under a stricter regime than anything else (depends on: 5, 6, 7)
Extracts payment processing, where mistakes are irreversible and regulatory. Payment is done before checkout orchestration, because checkout cannot be decomposed without a payment boundary already in place.
- Build the Payment service owning the integration with the three providers, including tokenization, authorisation, capture, refund and provider webhooks.
- Reduce PCI scope rather than expand it: no raw card data at rest in the new service, credentials in secrets management, no card data in logs or traces.
- Make every payment operation idempotent with explicit idempotency keys, because retries at peak are normal and double charges are not recoverable.
- Cut over provider by provider rather than all three at once, starting with the lowest-volume provider.
- Run the golden master across all decline, timeout, partial-authorisation and refund scenarios, and rehearse the fallback to the monolith's direct provider integration.
- Verify fraud detection and 3-D Secure paths explicitly, since they are usually the least covered and the most visible when they break.
- Land this cut early in an open window so it soaks well before the freeze.
15. Extract Order Management with an explicit state machine (depends on: 9, 10, 13, 14)
Extracts order management as the record of truth for the order lifecycle, after the services it depends on exist and are stable.
- Build the Order service with its own database and an explicit order state machine that validates every transition.
- Introduce event sourcing for order status so the audit trail satisfies regulators and fulfilment teams, and so state can be rebuilt after an incident.
- Consume events from payment, inventory and returns rather than polling or joining.
- Cut over reads first for the five teams that query orders, then writes, keeping the monolith's order tables as a reverse-CDC projection.
- Reconcile order counts and monetary totals hourly against the monolith throughout the transition. A monetary mismatch is an immediate rollback, not a ticket.
- Load-test concurrent order state transitions at peak, since the state machine becomes the new serialisation point.
16. Compose Checkout from independent services using a saga (depends on: 12, 13, 14, 15)
The highest-risk cut in the program, deliberately placed last among the transactional work and only after the components it orchestrates are individually proven.
- Build an orchestrating Checkout service that performs: cart validation, price computation, inventory reservation, payment authorisation, order creation.
- Implement compensating actions for every step: a failed authorisation releases the inventory reservation; a failed order creation voids the authorisation.
- Require idempotency keys end to end so a retried checkout cannot double-charge or double-reserve.
- Handle timeouts explicitly, including the peak case where inventory or pricing is slow. The saga must fail safe to a retryable state, never to a half-committed order.
- Mirror live checkout traffic to the new orchestration and compare full outcomes, including order totals and reservations, before any live traffic.
- Ramp live traffic during an open window only, and keep the monolith's checkout path fully functional and warm for rollback until it has survived a peak.
- Hold the six-week peak-readiness gate before this ramp and treat a failed gate as a stop, not a delay.
17. Migrate back-office, storefront and mobile clients off the monolith database (depends on: 16)
Moves the clients and the 300 back-office users onto the service APIs. Until this happens, the monolith's database remains a dependency even where the logic has already moved.
- Refactor back-office screens to consume service APIs through the gateway, replacing direct SQL access table by table, starting with orders and customers.
- Add aggregation endpoints where a screen needs several services, plus a short-lived cache so 300 staff do not multiply load on the new services.
- Update the server-rendered storefront to call service APIs while keeping the existing rendering path working behind a flag, so a rendering regression is a flag flip rather than a rollback.
- Point the mobile app at the gateway for migrated endpoints while keeping the old endpoints alive for un-updated app versions, since users do not upgrade on your schedule.
- Publish API versioning rules and deprecation windows so teams can change their services without coordinating with client releases.
- Load-test back-office behaviour with 300 concurrent staff on top of peak storefront traffic, since the two now share services.
18. Decommission the monolith core and harden for the second peak (depends on: 17)
Removes what is left of the monolith and proves the new architecture survives a peak. This step is as much about proving the state is coherent as about deleting code.
- Delete dead code and dropped tables module by module, only after a module has run a full peak or four clean weeks, whichever is longer.
- Keep read-only access to the old database for a defined period for historical and regulatory queries, then archive and decommission it.
- Replace the monolith's remaining cross-module reads with service calls or event-fed projections. The monolith should now be a small set of modules, or nothing at all.
- Re-run the full 12x load test against the new topology across all 8 countries, 3 currencies and 4 languages, and tune autoscaling, connection pools and broker partitions from the results.
- Run chaos game days: kill each service in turn and confirm the storefront degrades gracefully rather than failing completely.
- Confirm the peak-readiness gate before the second peak and publish its evidence. A failed gate defers remaining work rather than risking the peak.
- Write the exit report: final service boundaries, data ownership, runbooks, SLO history, the scope-ladder rung actually reached, and the list of work explicitly deferred to a follow-up program.
Note on proposal 1: Comprehensive and well-sequenced, but built on an unachievable capacity assumption — raising test coverage from 25% to 70% across a 2-million-line monolith — and it treats rollback of data as an afterthought rather than the central design constraint.
Adopted: Shadow traffic with checksum comparison of result sets before increasing canary traffic (step 9) — it is cheap, objective evidence and I fold it into my seam-verification step.
Adopted: Extract pricing as-is first and refactor afterwards (step 14) — the instinct to avoid rewriting rules nobody understands is correct, and I go further by banning the refactor from this program entirely.
Adopted: Keeping read-only access to the old database for two weeks after cutover (step 21) — cheap insurance, and I keep it for a full peak rather than two weeks.
Adopted: The observability-first foundation with distributed tracing (step 5) — tracing is also how you find real coupling, so it belongs before the architecture map, not after.
Rejected: Step 8, raising coverage to 70% for pricing, payment and order — pricing alone is 200,000 lines of unknown rules, so this would consume the entire engineering budget for the year and still fail; I replace it with golden-master characterization at the seam.
Rejected: Step 15, refactoring 200,000 lines of pricing rules into a DSL — this is scope creep inside a 12-month no-freeze window and is the single highest-risk change you could make to the least-understood module, so it is deferred in writing.
Rejected: Step 2, designing per-service database schemas with minimal denormalization before any extraction — designing the future schema of all 350 tables up front is waterfall and will be wrong; I assign ownership now and design each schema only when that module is cut.
Rejected: Step 21, decommissioning the legacy database before load testing and stabilization (steps 22–24 run after it) — that removes the rollback target while the new architecture is still unproven.
Note on proposal 3: The sharpest of the three on data strategy — CDC, transactional outbox and treating pricing as a black box are the right calls — but it compresses a two-peak, 12-month program into 10 steps with no calendar, and it never explains how independent deployability is actually achieved.
Adopted: CDC via Debezium plus a transactional outbox (step 3) — publishing monolith events by reading the WAL needs no application change, which is the lowest-risk possible start and the foundation of my four-stage cutover playbook.
Adopted: Characterization tests as a 'golden master' for the pricing module (step 7) — the only defensible way to move 200,000 lines of unknown country rules, and I make it a hard gate on the ramp.
Adopted: Real-time catalogue indexing to replace the nightly Lucene rebuild (step 4) — this reframes an extraction as a business win and buys political cover for the risky cuts.
Adopted: Search/catalogue as the read-only pilot with shadow-traffic comparison before any live routing.
Adopted: The point that the back-office's direct SQL access to the orders table must be removed explicitly (step 9) — it is the quiet dependency that keeps a database alive after its logic has moved.
Rejected: Step 7's framing that pricing moves into a new project while still reading a replica of the monolith's pricing tables — that leaves the service coupled to monolith schema and keeps the shared database alive; I transfer ownership of the pricing tables to the service at cutover.
Rejected: The ordering that places checkout orchestration (step 8) before payment extraction (step 9) — checkout cannot be decomposed without the payment boundary already in place, so I invert them and extract payment first.
Rejected: Step 4's plan to move catalogue straight onto dual read paths with a feature flag but no explicit soak window or reverse-sync — there is no defined way back once the flag is on for a while, so I add reverse CDC and a warm old index as the rollback path.
Rejected: Ten steps with no month-by-month calendar and no freeze windows — the hardest constraint in the brief (January and July sales must not be put at risk) is left entirely unaddressed.
--- PROPOSAL 3 (agent qwen3.8-flash_refine_3, alibaba/qwen3.8-flash) ---
Estimated complexity: high
Success metrics: - **Zero Downtime**: 100% availability maintained throughout the 12-month migration, excluding planned maintenance windows.
- **Rollback Speed**: Every service deployment is reversible in < 10 minutes via automated traffic switching at the Gateway.
- **Peak Performance**: The new architecture sustains 12x baseline load (480k orders/day) with < 200ms P95 latency for Checkout.
- **Data Integrity**: Zero discrepancies between pricing calculations of the old monolith and the new Pricing Service across 1 million replayed requests.
- **Independence**: Teams successfully deploy their services on a weekly cadence without coordinating with the monolith's bi-weekly release.
Steps (12):
1. Mobilization and Strategic Freeze Planning
Establish the governance and safety constraints for the migration. This step defines the 'no-touch' windows around peak seasons (January and July) and sets up the steering committee to manage the complexity of a 2M LOC codebase.
- **Team Alignment**: Reorganize the 5 teams into 'Service-First' pods. Each pod owns a target service extraction alongside their monolith maintenance duties.
- **Risk Framework**: Define strict 'Freeze Windows' (e.g., Dec 15–Jan 15, June 15–July 15) where no architectural changes are permitted, only bug fixes.
- **Dependency Mapping**: Create a 'Coupling Heatmap' identifying the most entangled modules (likely Pricing and Checkout) to isolate them for later phases.
2. Target Architecture and Domain Boundaries (depends on: 1)
Perform rigorous Domain-Driven Design (DDD) to define service boundaries. Given the 2M LOC and 350 tables, abstracting the domain is critical to prevent 'distributed monolith' outcomes.
- **Strategic DDD**: Map current modules to bounded contexts (Catalogue, Pricing, Orders, Identity, Fulfillment).
- **Database Decomposition Design**: Define the target data model for each service. Explicitly list which of the 350 tables move to which service and which cross-module joins must be replaced by API calls or events.
- **Contract Definition**: Draft API contracts (OpenAPI/GraphQL) for the core services to ensure backward compatibility with the existing frontend.
3. Core Infrastructure and Observability Foundation (depends on: 1)
Build the 'platform' that allows services to exist independently. You cannot safely extract services without first having the tools to see, test, and deploy them individually.
- **Kubernetes Cluster**: Provision a production-grade K8s environment with strict namespace isolation.
- **API Gateway**: Deploy a robust API Gateway (e.g., Kong, AWS ALB) to sit in front of the monolith. This is the 'Traffic Switcher' for the Strangler Fig pattern.
- **Observability Stack**: Implement Distributed Tracing (Jaeger), Centralized Logging (ELK/Loki), and Metrics (Prometheus). You must be able to trace a request from the gateway through a new service and back to the monolith.
- **CI/CD Pipelines**: Create independent deployment pipelines for services, allowing 15-minute rollback capabilities distinct from the monolith's 2-week cycle.
4. Test Harness: 'Golden Master' Characterization (depends on: 3)
Since testing the new logic against the old logic is the primary validation method, create an automated regression suite that captures the 'current truth' of the legacy system.
- **Input Logging**: Configure the monolith to log all incoming requests (and their responses) to a secure data lake, anonymizing PII.
- **Replay Engine**: Build a tool that takes a captured legacy request, sends it to both the legacy monolith and the new service, and diffs the responses.
- **Coverage Baseline**: Establish a 100% test coverage requirement for the *interfaces* being extracted. If you extract 'Search', you must have a test for every possible search query variant currently supported.
5. Extraction 1: Catalogue and Read-Only Search (depends on: 4)
The 'Low Hanging Fruit'. Extract the read-only Catalogue and Search capabilities first. This builds confidence and proves the Strangler Fig pattern without touching transactional data.
- **New Service**: Build 'Catalogue Service' that reads from a replicated Postgres (via logical replication) or a dedicated search DB (Elasticsearch).
- **Traffic Shift**: Configure the API Gateway to route `/products` and `/search` requests to the new service.
- **Fallback**: If the service fails, the gateway should immediately reroute to the legacy monolith (circuit breaker).
- **Optimization**: Replace the nightly Lucene rebuild with real-time indexing to instantly reflect price/inventory changes.
6. Extraction 2: Customer Identity and Profile (depends on: 5)
Extract user data handling. This decouples the 'who' from the 'what' (purchases), allowing independent authentication scaling.
- **Account Service**: Move user tables (Login, Profile, Address) to a dedicated service.
- **Session Migration**: Implement a token-passing strategy where the legacy monolith trusts tokens generated by the new Identity Service.
- **Read-Through Cache**: The legacy monolith should stop querying the user table directly; instead, it fetches user details from the Identity Service via an internal REST call or cached event.
- **Rollback**: Keep a 'sync-back' script to ensure if users are created in the new service, the legacy DB knows about them during the transition period.
7. Database Decoupling: The 'Anti-Corruption' Layer (depends on: 3, 5)
The most dangerous step. Breaking the 1.2TB DB entanglement requires intercepting the stored procedures. We stop writing to the shared DB from new services.
- **CDC Implementation**: Deploy Debezium to capture Postgres Write-Ahead Logs (WAL) into Kafka. This allows new services to be notified when the monolith updates data.
- **Outbox Pattern**: Refactor the monolith code so that when it writes to the DB, it also writes a 'domain event' to an internal Outbox table, which Debezium then publishes.
- **Read-Only Replicas**: Force new services to read from read-only replicas of the legacy DB to prevent them from causing lock contention on the master.
8. Extraction 3: Inventory and Fulfillment Interface (depends on: 7)
Move the inventory logic out. This separates the 'Stock' truth from the 'Order' truth, preparing for the complex checkout.
- **Inventory Service**: Create a service to hold the 'Single Source of Truth' for current stock levels.
- **Legacy Integration**: The monolith's checkout flow must now ask the Inventory Service to 'Reserve Stock' before processing payment.
- **Warehouse Sync**: Move the 15-minute file exchange logic into this service, isolating the legacy code from warehouse connectivity issues.
- **Concurrency Handling**: Implement optimistic locking in this service to handle high-concurrency 'reserve' requests during sales.
9. Extraction 4: Pricing and Promotions (The 'Black Box') (depends on: 8)
Extract the 200,000 LOC pricing engine. Do not rewrite the logic yet; wrap it. This is a 'Strangler Fig' step, not a refactoring step.
- **Encapsulation**: Move the existing pricing code (and its dependencies) into a new Spring Boot project called 'Pricing Service'.
- **Dependency Injection**: Replace direct DB access within the pricing logic with interfaces that call the Catalogue and Customer services via API.
- **Performance Parity**: Ensure the latency added by moving pricing to a separate network call is negligible (<50ms). Cache aggressively at the service level.
- **Validation**: Use the Golden Master (S4) to replay all historical orders and verify the new service returns the exact same price down to the cent.
10. Extraction 5: Checkout Orchestrator (Saga Pattern) (depends on: 9)
Replace the monolithic transaction with a distributed saga. This is the final piece of the transactional flow.
- **Orchestrator**: Build a lightweight service that coordinates the 'Checkout' process.
- **Saga Logic**: When an order is placed: 1. Call Pricing Service. 2. Call Inventory Service (Reserve). 3. Call Payment Gateway (External). 4. Call Order Service (Create).
- **Compensation**: If step 4 fails, the Orchestrator triggers 'Cancel Reserve' on the Inventory Service and 'Void' on the Payment Gateway.
- **Legacy Cutoff**: The monolith's 'Checkout' screen is replaced by a frontend form that calls this Orchestrator API.
11. Final Monolith Decomposition and Clean-up (depends on: 10)
At this stage, the monolith is hollowed out, containing mostly code that is called by the new services or legacy admin functions.
- **Admin Panel**: Move back-office functionality (Order management, Refunds) into a 'Management Service' that reads from the new event streams.
- **Code Deletion**: Delete the code for the extracted domains (Pricing, Search, Cart) from the monolith repository to enforce boundaries.
- **Database Cleanup**: Drop the tables owned by new services from the legacy monolith database.
- **Performance Tuning**: Optimize the remaining monolith for the only things it does: serving legacy redirects and perhaps a few 'orphaned' modules.
12. Peak Season Stress Test and Handover (depends on: 11)
Prepare for the high-volume events in Jan/July. Validate the new architecture holds under pressure.
- **Chaos Engineering**: Randomly kill the Search or Inventory services and verify the site degrades gracefully (e.g., 'Search temporarily unavailable') without crashing the checkout.
- **Load Testing**: Simulate 12x peak traffic using tools like Gatling/JMeter against the new APIs.
- **Runbooks**: Finalize operational playbooks for every team. Who owns what? How to restart a dead service? How to fallback to the monolith if the database fails?
Note on proposal 1: Excellent technical granularity but dangerously optimistic on the timeline of the Pricing extraction relative to peak seasons.
Adopted: Step 14: Adopted the 'Extract As-Is' (Black Box) strategy for the 200k LOC pricing module to mitigate rewrite risk, which was a superior approach to refactoring during migration.
Adopted: Step 1: Adopted the explicit 'Peak-Season Window Planning' to ensure changes don't hit the Jan/July freeze periods.
Rejected: Step 15: Rejected the idea of 'Phase 2 Refactoring' of pricing rules within the same 12-month plan; this adds unnecessary risk. Refactoring should happen *after* the migration is stable and the pressure is off.
Rejected: Step 9: Extracting 'Search/Catalogue' first is good, but their Step 9 dependencies assumed 'Deployment Pipeline' (Step 7) was fully robust. In reality, you must build the pipeline *before* attempting any extraction, which is why my S3 precedes all extractions.
Note on proposal 2: A solid high-level overview that correctly identifies the Strangler Fig pattern, but it underestimates the complexity of the Database decomposition.
Adopted: Step 3: Adopted the concept of the 'Strangler Fig Facade' at the API Gateway level as the central control point for the migration.
Adopted: Step 13: Adopted the 'Stored Procedure Refactoring' requirement, but moved it to be an implicit part of the 'Anti-Corruption Layer' (S7) strategy rather than a standalone step.
Rejected: Step 12: Rejected extracting Pricing *after* Order Management. If Pricing is a dependency of Order/Checkout, it must be extracted *before* Checkout to avoid calling back into the monolith for critical path logic.
Rejected: Step 7: Rejected 'Inventory Service' as the 7th step. Inventory is a critical dependency for Checkout. It should be extracted (S8) immediately before Checkout (S10) to ensure the reservation logic is ready for the distributed transaction.
Note on proposal 3: The strongest of the three proposals. It accurately reflects the 'Golden Master' strategy and the specific ordering required to handle the monolith's tight coupling.
Adopted: Step 4: Adopted the 'Golden Master' / 'Shadow Traffic' approach for testing. This is the only way to guarantee the pricing engine didn't break.
Adopted: Step 7: Adopted the explicit 'Event Storming' and 'Dependency Matrix' creation as a prerequisite to starting the build.
Rejected: Step 3: Rejected the 'Transaction Outbox' implementation *before* the 'Anti-Corruption' layer is established. You should first ensure you can intercept reads (S7), then establish writes (Outbox), as writes are higher risk.
Rejected: Step 9: Rejected the idea of moving the 'Back-office' (Management) last. It should be migrated alongside Orders (S10) or immediately after, as back-office staff need to manage the new orders as they flow in.
Your answer has these parts:
- "round_summary": two or three sentences on how the round went as a whole.
- "converging": true if the proposals of this round are more similar to each other than those of the previous round, false otherwise.
- "proposals": one entry per proposal of round 1, each with:
- "proposal": its number,
- "assessment": "improved", "worsened", "mixed" or "unchanged" with respect to its previous version ("no_previous_version" if that agent produced nothing in the previous round),
- "what_changed": a concise account of how it improved or worsened and why (three or four sentences at most),
- "improvements": a list of concrete gains (specific steps, metrics, structure),
- "regressions": a list of concrete losses (dropped steps, vaguer metrics, broken dependencies...),
- "taken": the ideas this proposal visibly adopted from the OTHER proposals of round 0 (not from its own previous version): one entry per idea with "from_proposal" (the number of the proposal it came from), "steps" (the numbers of the steps of that proposal where the idea lives, as listed above; empty if it is not tied to specific steps), "what" (the idea, one sentence) and "why" (how it was used or adapted, one sentence),
- "rejected": the ideas of the OTHER proposals of round 0 that this proposal visibly declined: an explicit contradiction, or a prominent idea it saw and left out while taking the opposite approach. Same fields; "why" gives the evidence (what the proposal does instead). Do not list mere omissions without evidence; an empty list is a valid answer.
[ROUND 2]
[SYSTEM]
You are an expert reviewer of multi-agent planning processes.
Several LLM agents drafted plans for a task, refined them over a number of rounds while seeing each other's proposals, and finally voted for the best one.
Be exhaustive but precise: name concrete steps, ideas and metrics, never generalities. Judge plans by their fitness for the task as stated, their realism, their completeness, the soundness of their order and dependencies, how measurable their success is and how they handle things going wrong.
You are an impartial evaluator, not a chronicler: assess the proposals and the process on their merits, never rationalise what happened or assume that the outcome was right.
After your analysis, answer in the requested structure.
Every text field you write will be read by a busy person, so write for them: short sentences, one idea each, in short paragraphs. Text fields accept Markdown: separate paragraphs with a blank line, use a bullet list when you enumerate things and plain paragraphs when you explain or argue, and bold at most one key phrase per paragraph. A text of more than three sentences must be split into paragraphs; never deliver a single unbroken block of text.
[HUMAN]
Task given to the agents: "A mid-size European fashion retailer runs its e-commerce on a 10-year-old monolith: Java 8 / Spring, about 2 million lines, one PostgreSQL database of 1.2 TB with 350 tables and heavy use of stored procedures and cross-module joins. It serves 8 countries, 3 currencies and 4 languages, with about 40,000 orders a day and peaks of 12x during sales. The monolith contains: the storefront (server-rendered, plus a separate mobile app hitting the same endpoints), catalogue and search (a Lucene index rebuilt nightly), pricing and promotions (the most complex module, 200,000 lines, with country-specific rules nobody fully understands), cart and checkout with three payment providers, order management, inventory synchronised every 15 minutes with the warehouse system via file exchange, customer accounts and loyalty, returns, and a back-office used by 300 staff. Deployments happen every two weeks as a single artefact with a 30-minute maintenance window; test coverage is 25% and mostly unit tests. Five teams of 8 developers, each organised around a business area but all committing to the same repository.
Plan the migration to independently deployable services over 12 months with no feature freeze, no unplanned downtime and the ability to roll back every step, preserving the peak-season capacity (sales in January and July must not be put at risk)."
This is round 2, a refinement round: every agent received ALL the proposals of round 1 and wrote a new plan, improving on them or taking a different approach. By convention, the previous version of proposal N is proposal N of round 1, written by the same model.
PROPOSALS OF ROUND 1 (the previous versions):
--- PROPOSAL 1 (agent claudeHaiku4.5_refine_1, anthropic/claude-haiku-4-5) ---
Estimated complexity: high
Success metrics: - Zero unplanned downtime during 12-month migration; all maintenance windows scheduled and communicated; zero production incidents caused by migration
- Peak seasons (January and July sales) proceed with zero degradation: 480k orders/day processed with p95 checkout latency < 5 seconds, payment authorization < 2 seconds, zero payment processing failures
- All eight services independently deployable: no code commits force monolith downtime; new service deployment < 5 minutes; deployment frequency increases from bi-weekly (monolith) to daily (services) where applicable
- Test coverage increased from 25% to 70%+ for all extracted services (Search, Inventory, Customer, Cart, Orders, Payments, Returns); characterization test suite for Pricing passes 100% before service extraction
- Every service deployment is rollback-able in < 30 minutes: documented procedures tested monthly; rollback automated where possible
- Data consistency validated: monthly reconciliation between service databases and monolith shows zero inconsistencies; dual-write period completes successfully (2 weeks per service)
- Order processing SLA maintained: cart → confirmation latency unchanged or improved; maintained under 5 seconds at peak load (480k orders/day)
- All five teams deploying independently by month 12: no cross-team deployment coordination required; each team owns service, deployment pipeline, on-call rotation
- Search latency improved or maintained: product availability reflected in search results within < 1 minute of inventory update (vs. previous nightly rebuild), baseline latency unchanged
- Inventory synchronization preserved: no missed 15-minute warehouse sync cycles during migration; 100% of daily inventory updates processed
- Back-office operations unaffected: 300 staff members seamlessly using new service APIs; service aggregation endpoints maintain < 500ms p95 latency
- Payment processing: zero regressions with all three payment providers; fraud detection remains active; PCI-DSS compliance maintained; idempotency prevents duplicate charges
- Event-driven architecture validated: Kafka message broker handles 480k messages/day at peak; no message loss or ordering violations
- Rollback capability proven: every step validated to be reversible; no permanent cutover without 30-day validation period and green light from peak season calendar
Steps (20):
1. Platform Foundation: Kubernetes, CI/CD, and Observability
Establish the technical foundation for independent service deployment and operation before touching the monolith architecture.
- Provision Kubernetes cluster with dev/staging/prod namespaces, or equivalent managed cloud platform (ECS/App Engine)
- Deploy centralized logging (ELK or Loki), metrics (Prometheus/Grafana), and distributed tracing (Jaeger)
- Implement CI/CD pipelines for independent service deployments (GitHub Actions/GitLab CI/ArgoCD)
- Set up secrets management (Vault) and configuration management (Consul/Spring Cloud Config)
- Create observability dashboards for: order throughput, latency percentiles (P50/P95/P99), error rates, database load
- Define SLOs and alerting: order processing latency p99 < 5 seconds, checkout success rate > 99.5%, payment auth speed < 2 seconds
2. Strangler Pattern Setup: API Gateway, Feature Flags, and Service Mesh (depends on: 1)
Deploy the infrastructure layer that enables gradual traffic migration from monolith to services without downtime.
- Deploy API gateway (Kong or AWS ALB) in front of monolith; all traffic routes through gateway
- Implement feature flag system (LaunchDarkly or Unleash) to decouple deployment from traffic routing
- Set up service mesh (Istio or Linkerd) for inter-service communication, mTLS, and circuit breakers
- Containerize monolith as-is (Docker) so it can run alongside new services
- Instrument monolith with event publishing capability: add transactional outbox table for domain events
- Create blast radius containment: rate limiting, bulkheads, and timeouts at gateway level
3. Domain Analysis and Service Boundary Definition via Event Storming (depends on: 2)
Map the monolith's business domains and dependencies to identify safe extraction sequence and service boundaries.
- Run event storming workshops with all five teams; map customer journeys (Browse → Cart → Checkout → Order → Fulfillment → Returns)
- Create dependency matrix: which tables, stored procedures, and methods are accessed by each domain
- Use code hotspot analysis (SonarQube, CodeScene) to find logical coupling and identify decoupling opportunities
- Define service extraction sequence based on coupling and business risk: prioritize read-heavy (Search), well-bounded (Inventory), and identity (Customer) over complex (Pricing, Checkout)
- Document all cross-module joins; mark which ones must be eliminated vs. which can tolerate eventual consistency
- Identify stored procedures that span multiple domains; plan refactoring or replication strategy
4. Peak Season Protection Framework and Change Freeze Calendar (depends on: 3)
Establish hard boundaries to protect January and July sales from destabilizing changes.
- Map annual peak periods: January sales (peak revenue), July sales, plus promotional events
- Define 6-week freeze windows: 4 weeks before + 2 weeks during each peak season; no major extractions or refactors during freeze
- Identify lowest-risk windows in each month for incremental changes (hotfixes, small extractions, data migrations only)
- Create rollback runbooks for every step: how to revert traffic routing, database changes, and service deployments in < 30 minutes
- Establish incident escalation and communication plan: business owners notified of any changes near peak season
- Plan load testing outside freeze windows: validate 12x capacity (480k orders/day) for each service before peak season
5. Pricing Module Characterization: Black Box Baseline and Test Suite (depends on: 3)
Thoroughly document the 200k LOC pricing engine behavior before any extraction attempt, eliminating unknown risk.
- Analyze and document all pricing rules: country-specific logic, currency handling, promotional rules, edge cases
- Create comprehensive characterization test suite: record input/output for all 8 countries × 3 currencies × major promotional scenarios
- This test suite becomes the 'golden master': any new pricing service must match 100% of outputs
- Build test data set covering: normal pricing, discounts, bulk pricing, regional pricing, multi-currency edge cases, seasonal promotions
- Document all dependencies: which customer attributes, product attributes, inventory levels, and time-based factors affect pricing
- Establish CI gate: pricing service extraction cannot proceed until characterization tests pass 100%
6. Test Coverage Improvement: Target 70% for Extract-Candidate Modules (depends on: 3)
Increase test confidence for modules scheduled for early extraction; reduce rollback risk from test blindness.
- Audit current test coverage by module; identify gaps in: Search, Catalogue, Inventory, Cart, Customer
- Implement integration tests for critical flows: order creation, payment processing, inventory updates, customer account creation
- Add contract tests (Pact) between modules to catch API breaking changes early
- Use mutation testing to verify test quality: tests must catch injected bugs
- Target 70%+ coverage for Search, Inventory, Customer, Cart, Payments modules
- Establish automated quality gates: no service extraction if module coverage < 60%; no production deployment if < 70%
- Create load test suites for peak scenarios: simulate 40k→480k order escalation for each module
7. Change Data Capture and Event-Driven Data Sync Infrastructure (depends on: 2, 5)
Build the plumbing to eliminate cross-module database joins and enable eventual consistency between services.
- Deploy CDC tool (Debezium with Kafka/Pulsar) to stream PostgreSQL WAL changes to message broker
- Refactor monolith to use transactional outbox pattern: all domain events written atomically in same transaction as business data
- Create event schema versioning: events must be backwards/forwards compatible as services evolve
- Implement dual-write mechanism: during transition, write to both monolith database and new service database
- Set up event relay: monolith publishes events (OrderPlaced, PaymentAuthorized, InventoryReserved) to Kafka
- Define eventual consistency model: which operations can tolerate delayed propagation vs. which require immediate consistency
8. Search and Catalogue Service Extraction: Read-Heavy Pilot Service (depends on: 6, 7)
Extract the first service: read-heavy, low transactional risk, validates the entire strangler fig pattern.
- Build new Catalogue and Search service: REST API for product lookup, search, and filtering
- Create new database schema (PostgreSQL): product data, categories, attributes; use Elasticsearch/OpenSearch for real-time search indexing
- Subscribe to CDC events from monolith: ProductUpdated events trigger real-time search index refresh (eliminates nightly Lucene rebuild, improves freshness to < 1 minute)
- Implement dual-read path: feature flag controls whether requests hit monolith Lucene or new Search service
- Use API gateway shadow traffic: send requests to both old and new service; compare responses; alert on differences
- Gradually shift traffic: 10% → 25% → 50% → 100% using feature flags and canary deployments
- Maintain dual-write for 2 weeks post-cutover to verify correctness; then deprecate monolith search code
9. Inventory Service Extraction: Real-Time Warehouse Synchronization (depends on: 7, 8)
Extract inventory as second service: async boundary, directly integrates with warehouse system, eliminates 15-minute sync latency.
- Build Inventory service: consumes warehouse file feed (SFTP/API) directly instead of monolith polling
- Create inventory database schema: stock levels, reservations, holds per product per location
- Publish inventory events: StockLevelChanged, ReservationCreated, ReservationReleased to Kafka
- Implement reservation system (prepare for saga pattern): inventory holds items during checkout, releases on order confirmation or timeout
- Dual-write monolith inventory data during transition: maintain consistency between old and new
- Test warehouse sync at peak load: ensure 15-minute sync windows do not slip under 480k daily orders
- Validate that all cart and checkout code calls inventory service via API (or consumes events) rather than direct SQL join
- Gradual traffic shift: test with non-critical inventory queries first, then critical paths
10. Customer and Loyalty Service Extraction: Identity Decoupling (depends on: 9)
Extract customer accounts and loyalty programs: enables independent auth scaling and multi-tenant loyalty rules.
- Build Customer service: JWT token generation, profile management, address management, identity verification
- Create customer database schema (separate from monolith): User, Address, Profile; replicate to read-only cache where needed
- Implement loyalty points service: handles country-specific loyalty rules (8 countries, different point accrual rates)
- Sync customer data via events: monolith publishes CustomerCreated, CustomerUpdated, CustomerDeleted to Kafka
- API gateway routes: /api/login, /api/profile, /api/loyalty to new Customer service; monolith drops these endpoints
- Ensure backwards compatibility: versioned API responses so old mobile app clients still work
- Test at peak concurrency: concurrent logins, loyalty point updates under 480k orders/day load
- Implement session management: distributed sessions (Redis-backed) so users stay logged in during monolith↔service transitions
11. Saga Pattern Framework and Distributed Transaction Orchestration (depends on: 7)
Implement the orchestration layer required for multi-service transactions before extracting payment and order services.
- Build saga pattern library: support both choreography (event-driven) and orchestration (centralized coordinator) patterns
- Implement compensating transactions: if payment fails during checkout, inventory reservation and pricing calc must roll back
- Add idempotency framework: all services accept idempotency-key headers; prevent duplicate charges, double-deductions
- Handle timeouts and retries: exponential backoff, circuit breakers, manual intervention for stuck sagas
- Create saga log: record saga execution with state transitions for auditing, debugging, and replay
- Test saga execution under peak load and network failures: simulate payment provider latency, inventory service timeouts
- Document saga flows: checkout saga (price → reserve inventory → authorize payment → create order), return saga, refund saga
- Implement distributed tracing: each saga step is traced end-to-end for observability
12. Payment Service Extraction: PCI-Scoped and Secure (depends on: 11)
Extract payment processing with extreme security rigor: handles card data, three payment providers, regulatory compliance.
- Build Payment service: integration with all three payment providers (tokenization, authorization, capture, refund)
- Implement PCI-DSS compliance: no raw card data in logs, encrypted transport, minimal data exposure in monolith
- Handle payment declines and fraud: integrate fraud detection, implement retry logic for transient failures
- Create idempotent payment requests: prevent double-charging if client retries or network fails mid-request
- Implement webhook handling: payment providers notify service of async events (captures, chargebacks, refunds)
- Design rollback procedure: if new service fails catastrophically, fall back to direct monolith payment handling (via feature flag)
- Load test: 500+ payments/sec at peak (baseline 40k orders/day → 480k orders/day = ~550 payments/sec)
- Test all three provider scenarios: happy path, declines, timeouts, chargebacks
13. Orders Service Extraction: Orchestrator for Checkout and Fulfillment (depends on: 12)
Extract order management: central service coordinating checkout saga and order lifecycle across all services.
- Build Order service: order creation, status tracking, order querying API for all business users (inventory, fulfillment, customer service teams)
- Implement checkout orchestrator: accepts cart (items, customer, delivery address) → triggers saga → creates order record on success
- Integrate with Payment service (authorize payment), Inventory service (reserve stock), Pricing service (calculate total), Customer service (loyalty points)
- Implement order state machine: validate state transitions (Pending → Confirmed → Shipped → Delivered), prevent invalid transitions
- Create order event stream: OrderCreated, PaymentAuthorized, InventoryReserved, OrderConfirmed, OrderShipped for other services to consume
- Use event sourcing: maintain immutable log of all order state changes for audit trail and replay capability
- Test concurrent order processing at peak load: 40k→480k orders/day; ensure no race conditions, duplicate orders, or lost transactions
- API design: query orders by customer ID, order ID, SKU, date range; sorting and filtering for back-office use
14. Cart Service Extraction: Stateful Session Management (depends on: 10)
Extract shopping cart as stateful service: decouples browsing/cart operations from order processing, independent scaling.
- Build Cart service: add/remove items, update quantities, persist session state, apply coupons/discounts
- Implement cart storage: Redis for session-backed stateless carts, or PostgreSQL with session affinity for persistent carts
- Integration with services: calls Catalogue service (product availability), Inventory service (stock check), Pricing service (cart totals)
- API design: cart operations (add/remove/view), subtotals with pricing breakdowns, coupon application
- Implement session stickiness: API gateway routes same user to same Cart service instance (or share Redis state)
- Test at peak concurrency: concurrent cart updates from same user (one browser tab → mobile app → browser again)
- Ensure idempotency: adding same item twice returns same cart state, no duplicates
- Gradual traffic shift: test with non-critical users first, then ramp up
15. Pricing Service Extraction: Black Box Wrapping and Golden Master Validation (depends on: 5, 13)
Extract pricing logic as black box service using characterization tests to ensure 100% correctness preservation.
- Move 200k LOC pricing logic into dedicated Pricing service with own codebase
- Service exposes API: accepts product IDs, customer attributes, location, time, inventory levels → returns price, applicable promotions, currency
- Use dedicated read-replica database with pricing tables only (no cross-joins to other domains)
- Run shadow mode traffic: send live pricing requests to both old monolith and new service; compare outputs; alert on any divergence
- Validation gate: pricing service must match characterization test suite 100% for all 8 countries, 3 currencies, all tested scenarios
- Feature flag control: gradually shift production traffic once shadow mode validates correctness
- Document decision: this service remains a black box (we don't refactor internal logic); future teams can safely extend without fear
- Plan Phase 2 refactoring separately: after service is stable in production, optionally decompose into rules engine (Drools) in future quarter
16. Returns Service Extraction and Order Lifecycle Completion (depends on: 13, 15)
Extract returns handling: completes order lifecycle, depends on Orders and Pricing services being stable.
- Build Returns service: process return requests, validate return eligibility, calculate refunds (using Pricing service), manage return shipping
- Integrate with Orders service: fetch order data, verify items purchased
- Integrate with Inventory service: return items to stock after confirmation
- Integrate with Payment service: process refunds back to original payment method
- API design: create return request, track return status, generate return shipping labels
- Implement return state machine: Requested → Approved → Shipped → Received → Refunded
- Consumer integration: back-office staff (or customer self-service) calls Returns service APIs instead of monolith
- Test return flows at peak load: validate no inventory/refund race conditions
17. Back-Office Service Aggregation and Staff User Experience (depends on: 13, 16)
Update back-office (300 staff) to consume new service APIs; eliminate monolith direct database access.
- Create service aggregation endpoints: orders endpoint calls Order + Payment + Inventory + Shipping services; returns endpoint calls Returns service
- Implement API gateway service discovery: back-office transparently calls services even if they move/scale
- Add caching layer: frequently accessed data (customer profiles, order lists) cached with TTL to reduce service latency
- Implement timeouts and graceful degradation: if one service is slow, show cached data or partial results
- Refactor back-office UI: replace monolith SQL queries with REST API calls
- Test with 300 concurrent staff users: search across orders/customers, filtering by date/status, bulk actions
- Implement distributed tracing: back-office requests are traced across all services for debugging
- Add retry logic: transient failures (network blips) automatically retry; permanent failures show user-friendly errors
18. Load Testing and Peak Capacity Validation Across Full System (depends on: 17)
Validate new distributed architecture handles peak load (480k orders/day) without degradation; stress test before peak seasons.
- Simulate realistic peak load: 480k orders/day (12x baseline), 8 countries, 3 currencies, 4 languages simultaneously
- Test sequence: base load → ramp to 480k → sustain for 30 minutes → spike to 1.5x peak → graceful degradation
- Measure latencies: checkout flow (cart → confirmation) p95 < 5 seconds, payment authorization < 2 seconds, search < 1 second
- Monitor service-level metrics: requests/sec, error rates, database query times, message broker throughput, cache hit rates
- Identify and optimize bottlenecks: pricing calculations, search queries, payment provider round-trip time, inventory reservations
- Test database connection pools: ensure no exhaustion or deadlocks under peak load
- Validate message broker (Kafka): 480k messages/day throughput, latency, durability
- Create realistic user behavior: product browsing → search → add to cart → checkout flows, not just load
- Fail-over testing: kill one service (e.g., Search); verify system degrades gracefully, no cascading failures
- Load test outside freeze windows; complete before January/July peak seasons
19. Team Reorganization and Independent Deployment Readiness (depends on: 18)
Reorganize teams around services to enable independent deployments and long-term operational autonomy.
- Reorganize five teams: from business-function-based (Pricing team, Fulfillment team) to stream-aligned (Search Service team, Orders Service team)
- Assign service ownership: each team owns their service's codebase, CI/CD pipeline, database schema, on-call rotation, SLOs
- Implement internal developer platform (IDP): golden path templates, self-service deployments, secrets rotation, observability dashboards
- Establish SLOs per service: error budget, latency targets, availability targets
- Create cross-team API contracts: service teams sign off on API changes; breaking changes trigger communication plan
- Set up inter-service communication: API versioning, deprecation periods, backward compatibility requirements
- Plan on-call: each team on-call for their service; pager rotation, incident response training
- Document service dependencies: which services call which; upstream/downstream impact analysis
20. Monolith Decommissioning and Legacy Code Cleanup (depends on: 19)
Safely retire monolith code once all services are stable and production-proven.
- Audit monolith codebase: identify dead code (Search, Catalogue, Inventory, Customer, Orders, Payments, Cart, Returns logic)
- Delete extracted service code from monolith; remove dual-write logic once service has proven stable (30+ days in production)
- Gradually reduce monolith database: archive or migrate old tables, remove cross-module stored procedures
- Plan monolith decommissioning: if monolith becomes shell (mostly unused), decide: keep as fallback or shut down completely
- Maintain 90-day read-only archive of monolith database for emergency historical queries and regulatory retention
- Update backup/recovery procedures: shift from single monolith snapshot to per-service snapshots
- Document architectural decisions: why services were split this way, what problems were solved, what trade-offs were made
- Create incident playbooks: common failure modes, resolution steps, escalation paths
- Close out migration project: update runbooks, retire temporary monitoring, establish steady-state operational procedures
- Celebrate: migration complete, new architecture proven at peak load, five teams deploying independently
Note on proposal 2: Proposal 2 provides solid platform foundations and clear sequencing, but underestimates the pricing risk and extracts checkout before foundational services stabilize.
Adopted: Step 2 (Platform Foundation) adopted: explicit Kubernetes, CI/CD, and observability setup reduces risk of independent deployments
Adopted: CDC/Debezium strategy (Step 13) adopted: event-driven data sync is cleaner than pure dual-write
Adopted: Service mesh setup adopted: explicit mention of Istio for mTLS and circuit breakers strengthens security
Adopted: Team reorganization aspect adopted: moving from business-function to stream-aligned teams is essential for long-term independence
Rejected: Orders service extraction (Step 11) happens before Payments (Step 16) in Proposal 2, but Orders depends on Payments working correctly; the sequence should be Payments first, then Orders as orchestrator
Rejected: Pricing extraction (Step 12) is too late and lacks risk mitigation: 200k LOC complex rules need characterization test baseline before any extraction attempt; Proposal 2 has no explicit golden master validation
Rejected: Only 15 steps is too coarse; Proposal 2 conflates multiple concerns (e.g., 'Post-Migration Optimization') that deserve explicit steps; testing, peak season protection, and validation deserve dedicated steps
Note on proposal 1: Proposal 1 is the most comprehensive with excellent peak-season protection and dual-write rigor, but the 24-step dependency chain creates unnecessary critical-path serialization.
Adopted: Peak-season protection (Step 4 in Proposal 1) adopted wholesale: 6-week freeze windows, 4 weeks before + 2 weeks during peaks, plus rollback runbooks < 30 minutes
Adopted: Test coverage roadmap adopted: systematic audit of current coverage, identify gaps, target 70% for extract candidates, quality gates that block extraction below 60%
Adopted: Dual-write strategy adopted: explicit step for managing consistency between monolith and new services during transition, 2-week validation period post-cutover
Adopted: Pricing phase 1/2 approach adopted: extract as-is first (black box), then optionally refactor rules engine later once stable (though Proposal 3's characterization test baseline is better)
Adopted: Saga pattern library adopted: explicit support for compensating transactions, idempotency, timeouts, and saga logging
Adopted: Load testing strategy adopted: multiple validation points, peak scenarios, chaos engineering game days
Rejected: 24-step sequence is overly granular and serialized; steps 9-20 could be parallelized more aggressively (Search extraction should not wait for Pricing characterization—they are independent)
Rejected: Test Coverage Improvement (Step 8 in Proposal 1) happens after Deployment Pipeline (Step 7), but test quality is a prerequisite for safe canary deployments; should be earlier
Rejected: Service extraction sequencing (Steps 9-15) follows a valid order but lacks explicit emphasis on read-heavy services first; Proposal 1 extracts Search late (Step 9) when it should be first to validate strangler pattern
Rejected: Pricing characterization is implicit in Step 14 ('Create feature tests that document all 200k LOC behavior') but not explicit; Proposal 3's black box approach is clearer and more rigorous about this critical risk
Note on proposal 3: Proposal 3 has excellent strategic insights on pricing risk (black box, characterization tests) and smart sequencing, but is too compressed—10 steps lack operational detail on rollback, dual-write, and peak season protection.
Adopted: Pricing black box strategy adopted: wrap existing 200k LOC logic as-is into a service; use characterization tests (golden master) for validation; shadow mode traffic for correctness verification before production traffic shift
Adopted: Real-time search indexing adopted: move from nightly Lucene rebuild to real-time Elasticsearch/OpenSearch; subscribe to CDC events for instant product freshness (< 1 minute vs. nightly)
Adopted: Event storming workshops adopted: explicit domain analysis step (Step 2 in Proposal 3) before architecture decisions
Adopted: Characterization test emphasis adopted: Proposal 3 correctly identifies this as critical risk mitigation for pricing, making it explicit and foundational
Adopted: Service mesh and observability foundation adopted: Proposal 3 emphasizes these early (Step 1)
Rejected: Only 10 steps lacks operational granularity: rollback procedures, peak season freeze windows, test coverage improvement, and data migration runbooks are underspecified or missing
Rejected: Peak season protection mentioned only in final step (Step 10) but should be early and explicit; Proposal 3 risks scheduling extractions during peak windows if planning happens late
Rejected: Returns service not explicitly extracted (Step 8 in Proposal 3 is vague); returns touches Orders, Inventory, and Payments and deserves its own step with clear dependencies and validation
Rejected: Dual-write and CDC strategy (Step 3 in Proposal 3) lacks detail on how monolith and services stay consistent; transactional outbox pattern deserves explicit treatment, not bundled with database isolation
--- PROPOSAL 2 (agent deepseek-flash_refine_2, deepseek/deepseek-flash) ---
Estimated complexity: high
Success metrics: - Independent deployability: 100% of releases to extracted services require no coordination with another team and no monolith release, demonstrated for at least 6 services by month 9.
- Independent deployability precedes extraction: at least 4 of the 5 teams release their own artefacts without being separate services by month 5.
- The 30-minute maintenance window is retired by month 6; no release after that date requires a planned outage.
- Deployment lead time from merge to production for a single service is 30 minutes or less, and each team releases at least 3 times per week by month 6.
- Zero unplanned downtime attributable to the migration across the 12 months; platform availability of 99.95% or better inside each peak window.
- Both January and July peaks pass with no migration-caused incident: 12x baseline load sustained, checkout p99 under 5 seconds, error rate under 0.5%, no queue backlog beyond 5 minutes.
- 100% of migration increments that reach production have a rollback demonstrated in a game day and executable in under 30 minutes.
- Hourly data reconciliation shows under 0.001% discrepancy on row counts and checksums per module, with zero unexplained business-invariant violations.
- Cross-module database joins and cross-module writes originating in application code are zero for every module at the moment it is extracted, enforced by database roles and CI checks rather than by review.
- Pricing parity: 100% agreement with the golden master on a corpus of at least 1,000,000 historical requests across all 8 countries, 3 currencies and 4 languages, both before and after cutover.
- Stored procedures touching more than one module's tables: zero for every extracted module.
- Search freshness improves from a nightly rebuild to under 30 seconds between a product change and its visibility in search results.
- Warehouse inventory freshness improves from 15 minutes to under 2 minutes end to end.
- 100% of public APIs of extracted services have golden-master or consumer-driven contract coverage; line coverage is tracked only for newly written service code, where it reaches 80%.
- The peak-readiness gate is passed with published evidence six weeks before both peaks, covering 100% of its defined checks.
- Scope ladder rungs 1–6 are complete within 12 months, or the program stops at a rung boundary in a documented, coherent, peak-safe state.
Steps (18):
1. Program setup, peak-aware calendar, rollback charter and scope ladder
Turns the brief's constraints into an operating rhythm that everything later obeys. The binding constraint in this objective is the calendar, not the technology, so the calendar is decided first.
- Run a two-week inception to baseline the current state: build time, deployment lead time, change failure rate, MTTR, MTTR, per-module change frequency, database load profile. Progress must be measurable, not asserted.
- Declare hard freezes from 1 December to 15 January and 1 June to 15 July. During a freeze only rollback-enabling and hardening changes are allowed.
- Confirm the two open delivery windows of the year (roughly February–May and August–November) and accept in writing that only these windows carry migration increments.
- Set the soak rule: no change on the checkout path lands within four weeks of a freeze; anything that would violate it is deferred to the next window.
- Define the peak-readiness gate that runs six weeks before each peak: 12x load test, capacity headroom check, rollback rehearsal, error-budget review. The gate is pass/fail and its evidence is published.
- Write the rollback charter: every increment ships an expand/contract database change, a feature-flag kill switch, and a rehearsal recorded in a game day. No go-live without a rehearsed rollback.
- Publish the scope ladder: a ranked list where rungs 1–6 deliver the core objective and rungs 7+ are optional. Slippage means stopping at a rung boundary, never mid-increment.
- Set the capacity budget at 40–50% of the five teams' capacity for migration alongside normal feature work, and staff the ladder to fit that budget rather than to fill the year.
- Create a migration enablement squad of six engineers drawn on rotation from the five teams. It owns the platform, the shared cuts and the risky shared data work.
2. Executable architecture map, table ownership and boundary enforcement (depends on: 1)
Produces an architecture map that the build itself enforces. Five teams committing to one repository will silently re-couple anything that is separated and not policed, so enforcement is part of the map, not a later step.
- Instrument the monolith with distributed tracing and let it run four weeks. Real call paths beat static imports for finding true coupling.
- Build a table-to-module and query-to-module map by parsing every SQL statement, ORM mapping and stored procedure in the codebase, cross-checked against the database's own query logs.
- Score each candidate service on four axes: coupling, transactional risk, change frequency and peak-path criticality. This ranking, not intuition, drives the extraction order.
- Assign every one of the 350 tables to exactly one owning module. Tables nobody can own are declared contested and scheduled into the data work of S7.
- Add ArchUnit rules to CI that fail the build on any new cross-module Java dependency, with existing violations frozen into a baseline file that may only shrink.
- Add a SQL linter to CI that fails on cross-module joins and cross-module writes, with the same shrinking baseline.
- Publish the target service list, the owning team per service, and the reasoning as architecture decision records.
- Hold a mid-program review at month six to re-rank the scope ladder using what the map actually showed. This is the one planned re-planning point of the program.
3. Delivery platform: per-module pipelines, gateway, feature flags, environments (depends on: 1, 2)
Builds the delivery and traffic machinery that makes every later step reversible. No module is extracted until its team can deploy, flag and route on its own.
- Extend the platform foundation on Kubernetes (or the existing container platform if one exists) with one namespace per service, quotas and autoscaling policies sized for a 12x peak.
- Put an API gateway in front of the monolith as the strangler entry point. Storefront, mobile and back-office traffic all flow through it from day one, even while it routes everything to the monolith.
- Give every module its own CI/CD pipeline and its own environment. The monolith keeps its current pipeline for hotfixes until S5 replaces it.
- Deploy a feature-flag service and require every new call path to be flag-guarded. Flags are the primary rollback instrument for the whole program.
- Introduce secrets management and per-environment configuration so changing behaviour never requires a monolith redeploy.
- Define golden-path templates for a new service: build, pipeline, observability, health checks, flag integration, database migration tool. Extraction must not start from a blank page.
- Reserve two permanent environments: a full-size production-like soak environment and a load-test environment capable of generating 12x traffic against production-shaped data.
4. Observability, business SLOs, error budgets and the automated rollback controller (depends on: 3)
Makes the system observable enough that a canary is judged automatically and reverted without a human guessing. This is the prerequisite for the rollback promise made in every later step.
- Deploy centralized logging, metrics and distributed tracing, with trace correlation working across the gateway, the monolith and every new service from the start.
- Instrument the monolith's blind spots: query latency by module, connection-pool saturation, Lucene rebuild duration, warehouse file-exchange lag.
- Define SLOs on business outcomes, not infrastructure: checkout success rate, order confirmation p99, search latency, payment authorisation rate, price computation latency, warehouse sync freshness.
- Attach an error budget to each SLO and write the policy: when a service burns budget, its rollout stops automatically and its flags revert. No negotiation during a peak.
- Build the rollback controller: on error-rate or latency divergence beyond threshold during a canary, the gateway shifts traffic back and flags are disabled without human action.
- Create per-service dashboards a tired engineer can read at 03:00, plus one program dashboard showing progress against the scope ladder.
5. Split the deployment unit and retire the 30-minute maintenance window (depends on: 2, 3)
Delivers the objective's headline — independently deployable units — before any process separation, by splitting the build and the release train while the code still runs together. This is the cheapest large win available and it removes the maintenance window.
- Split the single artefact into one build per owning module with a shared parent, so a module can be built, tested and released on its own.
- Allow modules to be released as separate artefacts on the existing runtime first. Independent deployability is a build and release property long before it is a topology property.
- Retire the two-week coordinated release train. Each team gets its own pipeline, cadence and on-call rota, with the gateway and schema compatibility as the contract between teams.
- Adopt expand/contract database migrations so schema and code changes no longer have to ship together.
- Replace the maintenance window with blue-green deployment on two identical stacks, traffic switched at the gateway and rollback performed by switching back.
- Measure and publish the result: deployment lead time, deployment frequency per team, and the share of releases that needed no coordination with another team.
6. Seam-level verification: golden master, contracts, shadow diffing, reconciliation (depends on: 2, 3)
Replaces the impossible goal of blanket test coverage with verification exactly where the cut will be made. A two-million-line monolith cannot reach 70% coverage in a year; a service boundary can be verified to a very high standard in weeks.
- Build a characterization harness that records real production requests and replays them against the monolith, capturing full responses as a golden master. This is the safety net for every extraction.
- Require every extracted service to pass the golden master on its public API before it takes live traffic, producing a diff report rather than a pass/fail.
- Use consumer-driven contract tests between the monolith and each new service, and between services, so a change on one side breaks a build instead of production.
- Run shadow traffic: mirror live requests to the new service, compare responses field by field, and gate the traffic ramp on the divergence rate.
- Build per-module data reconciliation as a first-class test: row counts, checksums and business invariants compared on a schedule, with an owner and an alert threshold.
- Add synthetic canary transactions that execute a real checkout, return and search every few minutes and alert on functional regression before customers notice.
- Explicitly do not pursue blanket line coverage of the monolith. Track coverage only for newly written service code, where the target is 80%.
7. Data platform: schema ownership, join elimination, CDC, outbox, four-stage cutover playbook (depends on: 2, 3, 6)
The hardest part of the program and the part most plans under-specify. It does not depend on service extraction, so it starts in month one and runs in parallel with everything else.
- Enforce ownership inside the database itself: one PostgreSQL role per module, able to write only its own schema and to read others only through defined views. Cross-schema writes are rejected by the database, not by convention.
- Inventory every stored procedure, attribute it to one module, and either move it into that module's code or leave it as a module-private function. After a module is extracted, no stored procedure may touch two modules' tables.
- Eliminate cross-module joins one at a time, replacing each with an API call, an event-fed materialized read model or a duplicated read-only projection. Track the count per module and drive it to zero before that module is cut.
- Stand up change data capture with Debezium reading the PostgreSQL WAL into Kafka. This publishes monolith domain events with no application change, the lowest-risk start available.
- Add a transactional outbox for new services so their events and their state changes commit together.
- Adopt one reusable four-stage cutover playbook per module and apply it identically every time. Stage A: the service owns its schema logically, reads from CDC into its own store, and serves shadow traffic only. Stage B: reads cut over, the monolith stays system of record. Stage C: writes cut over, and the monolith's tables become read-only replicas fed by reverse CDC from the service. Stage D: old tables and dead code are dropped only after a full peak or four clean weeks, whichever is longer.
- Make stage C genuinely reversible: because the sync direction can be flipped, rolling back a write cutover is a configuration change plus a reconciliation pass, not a data restore.
- Build the reconciliation service now so every later cutover has an objective consistency check with thresholds and owners.
- Schedule the 1.2 TB storage migration as background work: new services start on the existing cluster with their own schemas, and physical split happens only once a module is stable.
8. Extract Catalog and Search (depends on: 5, 6, 7)
First extraction, chosen because it is read-heavy, mostly isolated and carries no transactional risk. It also pays for itself: replacing the nightly Lucene rebuild with real-time indexing is a visible business win that buys political cover for the harder cuts.
- Create a Catalog service owning product, category and media tables plus its own search index.
- Feed it from CDC so product and price changes appear in search within seconds instead of after a nightly rebuild.
- Route through the gateway behind a flag and ramp 1% → 5% → 25% → 50% → 100%, with the rollback controller able to revert to the monolith's internal Lucene path at any point.
- Run shadow traffic and compare result sets before any live traffic, then keep the old index warm for two weeks after full cutover.
- Verify the mobile app, which hits the same endpoints, inside the same ramp; its behaviour is part of the go/no-go.
- Land this cut in an open delivery window and let it soak at least four weeks before the freeze.
9. Extract Returns as the first write-path and own-database proof (depends on: 5, 6, 7)
Second extraction and the first that owns writes and a database. Returns is chosen because it is off the peak-critical path, has modest coupling, and exercises the full four-stage playbook at low stakes.
- Build the Returns service with its own schema, consuming order and customer events rather than joining their tables.
- Run the playbook end to end: shadow reads, read cutover, then write cutover with reverse CDC keeping the monolith's tables current.
- Prove the rollback path in a game day before write cutover, including a reconciliation pass and a re-run of the golden master.
- Keep the back-office returns screens on the monolith for now, so staff workflow is untouched by this step.
- Record every friction point and correct the playbook. The real output of this step is a proven, reusable procedure, not just one service.
10. Extract Inventory and replace the 15-minute warehouse file exchange (depends on: 5, 6, 7)
Removes one of the sharpest coupling points in the system and unblocks the checkout work. Inventory is extracted in parallel with the other early cuts because it couples the monolith to an external warehouse process rather than to other modules.
- Build the Inventory service to ingest the warehouse feed directly and publish stock-level events.
- Preserve the existing file-based interface for the first weeks, running the new ingest in parallel with the legacy feed and reconciling hourly until they agree.
- Keep the monolith's inventory tables as a projection fed by events, so cart and checkout keep working unchanged during the cut.
- Design reservation semantics now — reserve, confirm, release, with expiry — even though checkout is not yet extracted. The API is needed later and is cheap to get right here.
- Load-test inventory ingest at 12x, because the warehouse feed schedule and the sales peaks do not always coincide.
- Cut over reads first, then writes, with the rollback controller able to restore the file feed as the source of truth.
11. Extract Customer Accounts and Loyalty, with a conservative auth strategy (depends on: 5, 6, 7, 9)
Extracts customer accounts and loyalty, including the authentication decision. Auth is the step that most often derails e-commerce migrations, so the auth path is deliberately moved last and guarded hardest.
- Build the Customer service owning profile, address and loyalty tables, with country-specific loyalty rules expressed as data where possible and as code where not.
- Keep authentication in the monolith for the first phase. Move token issuance only once customer data is stable, and never within four weeks of a freeze.
- Introduce distributed session handling and a token-validation API so services can verify identity without querying the monolith database.
- Cut over reads, then writes, with reverse CDC, validating against the golden master across all 8 countries and 4 languages.
- Verify the mobile app's session behaviour explicitly, since it holds long-lived sessions the storefront does not.
- Move loyalty point accrual and redemption last, because a loyalty error is a customer-visible financial error, not a technical incident.
12. Extract Cart (depends on: 8, 10, 11)
Extracts the cart, which is stateful and sits directly in front of checkout. It is done before pricing and checkout because both need a stable cart boundary to call.
- Build the Cart service on Redis for session and line-item state, validating products and inventory through service calls rather than database joins.
- Make every cart operation idempotent, because a retried add or remove during a peak must not duplicate a line item.
- Keep the cart tables in the monolith as a read-only projection fed by events, for rollback and for the not-yet-migrated back-office screens.
- Ramp traffic while monitoring cart abandonment rate as the business metric, since cart latency shows up as lost revenue rather than as errors.
- Exercise anonymous and authenticated carts separately; they follow different paths and fail in different ways.
- Land this cut in an open window with a full four-week soak before the freeze.
13. Extract Pricing and Promotions as an unchanged black box (depends on: 5, 6, 7)
Extracts the 200,000-line pricing module without rewriting it. The rules are not understood by anyone, so they are wrapped and characterized rather than reverse-engineered. Rule decomposition, documentation and a DSL are explicitly out of scope for these twelve months.
- Build a golden master corpus from at least a million real historical pricing requests and their recorded outputs, covering all 8 countries, 3 currencies and 4 languages, plus every promotion type that can be discovered.
- Refactor only the module's dependencies: pricing must obtain customer, product and inventory data through interfaces rather than direct database access, so it can be lifted out.
- Move the pricing code into its own service unchanged, owning its tables after cutover, and expose a single decision API.
- Run it in shadow mode for at least four weeks against live traffic, comparing every computed price with the monolith. Any divergence blocks the ramp.
- Cut over behind a flag with per-country ramps, since a pricing error is a financial and legal exposure rather than a technical incident.
- Keep the in-monolith evaluator available and warm as the rollback path for at least one full peak after cutover.
- State in writing that rule decomposition is deferred to a follow-up program, so it does not creep back into this one.
14. Extract Payment under a stricter regime than anything else (depends on: 5, 6, 7)
Extracts payment processing, where mistakes are irreversible and regulatory. Payment is done before checkout orchestration, because checkout cannot be decomposed without a payment boundary already in place.
- Build the Payment service owning the integration with the three providers, including tokenization, authorisation, capture, refund and provider webhooks.
- Reduce PCI scope rather than expand it: no raw card data at rest in the new service, credentials in secrets management, no card data in logs or traces.
- Make every payment operation idempotent with explicit idempotency keys, because retries at peak are normal and double charges are not recoverable.
- Cut over provider by provider rather than all three at once, starting with the lowest-volume provider.
- Run the golden master across all decline, timeout, partial-authorisation and refund scenarios, and rehearse the fallback to the monolith's direct provider integration.
- Verify fraud detection and 3-D Secure paths explicitly, since they are usually the least covered and the most visible when they break.
- Land this cut early in an open window so it soaks well before the freeze.
15. Extract Order Management with an explicit state machine (depends on: 9, 10, 13, 14)
Extracts order management as the record of truth for the order lifecycle, after the services it depends on exist and are stable.
- Build the Order service with its own database and an explicit order state machine that validates every transition.
- Introduce event sourcing for order status so the audit trail satisfies regulators and fulfilment teams, and so state can be rebuilt after an incident.
- Consume events from payment, inventory and returns rather than polling or joining.
- Cut over reads first for the five teams that query orders, then writes, keeping the monolith's order tables as a reverse-CDC projection.
- Reconcile order counts and monetary totals hourly against the monolith throughout the transition. A monetary mismatch is an immediate rollback, not a ticket.
- Load-test concurrent order state transitions at peak, since the state machine becomes the new serialisation point.
16. Compose Checkout from independent services using a saga (depends on: 12, 13, 14, 15)
The highest-risk cut in the program, deliberately placed last among the transactional work and only after the components it orchestrates are individually proven.
- Build an orchestrating Checkout service that performs: cart validation, price computation, inventory reservation, payment authorisation, order creation.
- Implement compensating actions for every step: a failed authorisation releases the inventory reservation; a failed order creation voids the authorisation.
- Require idempotency keys end to end so a retried checkout cannot double-charge or double-reserve.
- Handle timeouts explicitly, including the peak case where inventory or pricing is slow. The saga must fail safe to a retryable state, never to a half-committed order.
- Mirror live checkout traffic to the new orchestration and compare full outcomes, including order totals and reservations, before any live traffic.
- Ramp live traffic during an open window only, and keep the monolith's checkout path fully functional and warm for rollback until it has survived a peak.
- Hold the six-week peak-readiness gate before this ramp and treat a failed gate as a stop, not a delay.
17. Migrate back-office, storefront and mobile clients off the monolith database (depends on: 16)
Moves the clients and the 300 back-office users onto the service APIs. Until this happens, the monolith's database remains a dependency even where the logic has already moved.
- Refactor back-office screens to consume service APIs through the gateway, replacing direct SQL access table by table, starting with orders and customers.
- Add aggregation endpoints where a screen needs several services, plus a short-lived cache so 300 staff do not multiply load on the new services.
- Update the server-rendered storefront to call service APIs while keeping the existing rendering path working behind a flag, so a rendering regression is a flag flip rather than a rollback.
- Point the mobile app at the gateway for migrated endpoints while keeping the old endpoints alive for un-updated app versions, since users do not upgrade on your schedule.
- Publish API versioning rules and deprecation windows so teams can change their services without coordinating with client releases.
- Load-test back-office behaviour with 300 concurrent staff on top of peak storefront traffic, since the two now share services.
18. Decommission the monolith core and harden for the second peak (depends on: 17)
Removes what is left of the monolith and proves the new architecture survives a peak. This step is as much about proving the state is coherent as about deleting code.
- Delete dead code and dropped tables module by module, only after a module has run a full peak or four clean weeks, whichever is longer.
- Keep read-only access to the old database for a defined period for historical and regulatory queries, then archive and decommission it.
- Replace the monolith's remaining cross-module reads with service calls or event-fed projections. The monolith should now be a small set of modules, or nothing at all.
- Re-run the full 12x load test against the new topology across all 8 countries, 3 currencies and 4 languages, and tune autoscaling, connection pools and broker partitions from the results.
- Run chaos game days: kill each service in turn and confirm the storefront degrades gracefully rather than failing completely.
- Confirm the peak-readiness gate before the second peak and publish its evidence. A failed gate defers remaining work rather than risking the peak.
- Write the exit report: final service boundaries, data ownership, runbooks, SLO history, the scope-ladder rung actually reached, and the list of work explicitly deferred to a follow-up program.
Note on proposal 1: Comprehensive and well-sequenced, but built on an unachievable capacity assumption — raising test coverage from 25% to 70% across a 2-million-line monolith — and it treats rollback of data as an afterthought rather than the central design constraint.
Adopted: Shadow traffic with checksum comparison of result sets before increasing canary traffic (step 9) — it is cheap, objective evidence and I fold it into my seam-verification step.
Adopted: Extract pricing as-is first and refactor afterwards (step 14) — the instinct to avoid rewriting rules nobody understands is correct, and I go further by banning the refactor from this program entirely.
Adopted: Keeping read-only access to the old database for two weeks after cutover (step 21) — cheap insurance, and I keep it for a full peak rather than two weeks.
Adopted: The observability-first foundation with distributed tracing (step 5) — tracing is also how you find real coupling, so it belongs before the architecture map, not after.
Rejected: Step 8, raising coverage to 70% for pricing, payment and order — pricing alone is 200,000 lines of unknown rules, so this would consume the entire engineering budget for the year and still fail; I replace it with golden-master characterization at the seam.
Rejected: Step 15, refactoring 200,000 lines of pricing rules into a DSL — this is scope creep inside a 12-month no-freeze window and is the single highest-risk change you could make to the least-understood module, so it is deferred in writing.
Rejected: Step 2, designing per-service database schemas with minimal denormalization before any extraction — designing the future schema of all 350 tables up front is waterfall and will be wrong; I assign ownership now and design each schema only when that module is cut.
Rejected: Step 21, decommissioning the legacy database before load testing and stabilization (steps 22–24 run after it) — that removes the rollback target while the new architecture is still unproven.
Note on proposal 3: The sharpest of the three on data strategy — CDC, transactional outbox and treating pricing as a black box are the right calls — but it compresses a two-peak, 12-month program into 10 steps with no calendar, and it never explains how independent deployability is actually achieved.
Adopted: CDC via Debezium plus a transactional outbox (step 3) — publishing monolith events by reading the WAL needs no application change, which is the lowest-risk possible start and the foundation of my four-stage cutover playbook.
Adopted: Characterization tests as a 'golden master' for the pricing module (step 7) — the only defensible way to move 200,000 lines of unknown country rules, and I make it a hard gate on the ramp.
Adopted: Real-time catalogue indexing to replace the nightly Lucene rebuild (step 4) — this reframes an extraction as a business win and buys political cover for the risky cuts.
Adopted: Search/catalogue as the read-only pilot with shadow-traffic comparison before any live routing.
Adopted: The point that the back-office's direct SQL access to the orders table must be removed explicitly (step 9) — it is the quiet dependency that keeps a database alive after its logic has moved.
Rejected: Step 7's framing that pricing moves into a new project while still reading a replica of the monolith's pricing tables — that leaves the service coupled to monolith schema and keeps the shared database alive; I transfer ownership of the pricing tables to the service at cutover.
Rejected: The ordering that places checkout orchestration (step 8) before payment extraction (step 9) — checkout cannot be decomposed without the payment boundary already in place, so I invert them and extract payment first.
Rejected: Step 4's plan to move catalogue straight onto dual read paths with a feature flag but no explicit soak window or reverse-sync — there is no defined way back once the flag is on for a while, so I add reverse CDC and a warm old index as the rollback path.
Rejected: Ten steps with no month-by-month calendar and no freeze windows — the hardest constraint in the brief (January and July sales must not be put at risk) is left entirely unaddressed.
--- PROPOSAL 3 (agent qwen3.8-flash_refine_3, alibaba/qwen3.8-flash) ---
Estimated complexity: high
Success metrics: - **Zero Downtime**: 100% availability maintained throughout the 12-month migration, excluding planned maintenance windows.
- **Rollback Speed**: Every service deployment is reversible in < 10 minutes via automated traffic switching at the Gateway.
- **Peak Performance**: The new architecture sustains 12x baseline load (480k orders/day) with < 200ms P95 latency for Checkout.
- **Data Integrity**: Zero discrepancies between pricing calculations of the old monolith and the new Pricing Service across 1 million replayed requests.
- **Independence**: Teams successfully deploy their services on a weekly cadence without coordinating with the monolith's bi-weekly release.
Steps (12):
1. Mobilization and Strategic Freeze Planning
Establish the governance and safety constraints for the migration. This step defines the 'no-touch' windows around peak seasons (January and July) and sets up the steering committee to manage the complexity of a 2M LOC codebase.
- **Team Alignment**: Reorganize the 5 teams into 'Service-First' pods. Each pod owns a target service extraction alongside their monolith maintenance duties.
- **Risk Framework**: Define strict 'Freeze Windows' (e.g., Dec 15–Jan 15, June 15–July 15) where no architectural changes are permitted, only bug fixes.
- **Dependency Mapping**: Create a 'Coupling Heatmap' identifying the most entangled modules (likely Pricing and Checkout) to isolate them for later phases.
2. Target Architecture and Domain Boundaries (depends on: 1)
Perform rigorous Domain-Driven Design (DDD) to define service boundaries. Given the 2M LOC and 350 tables, abstracting the domain is critical to prevent 'distributed monolith' outcomes.
- **Strategic DDD**: Map current modules to bounded contexts (Catalogue, Pricing, Orders, Identity, Fulfillment).
- **Database Decomposition Design**: Define the target data model for each service. Explicitly list which of the 350 tables move to which service and which cross-module joins must be replaced by API calls or events.
- **Contract Definition**: Draft API contracts (OpenAPI/GraphQL) for the core services to ensure backward compatibility with the existing frontend.
3. Core Infrastructure and Observability Foundation (depends on: 1)
Build the 'platform' that allows services to exist independently. You cannot safely extract services without first having the tools to see, test, and deploy them individually.
- **Kubernetes Cluster**: Provision a production-grade K8s environment with strict namespace isolation.
- **API Gateway**: Deploy a robust API Gateway (e.g., Kong, AWS ALB) to sit in front of the monolith. This is the 'Traffic Switcher' for the Strangler Fig pattern.
- **Observability Stack**: Implement Distributed Tracing (Jaeger), Centralized Logging (ELK/Loki), and Metrics (Prometheus). You must be able to trace a request from the gateway through a new service and back to the monolith.
- **CI/CD Pipelines**: Create independent deployment pipelines for services, allowing 15-minute rollback capabilities distinct from the monolith's 2-week cycle.
4. Test Harness: 'Golden Master' Characterization (depends on: 3)
Since testing the new logic against the old logic is the primary validation method, create an automated regression suite that captures the 'current truth' of the legacy system.
- **Input Logging**: Configure the monolith to log all incoming requests (and their responses) to a secure data lake, anonymizing PII.
- **Replay Engine**: Build a tool that takes a captured legacy request, sends it to both the legacy monolith and the new service, and diffs the responses.
- **Coverage Baseline**: Establish a 100% test coverage requirement for the *interfaces* being extracted. If you extract 'Search', you must have a test for every possible search query variant currently supported.
5. Extraction 1: Catalogue and Read-Only Search (depends on: 4)
The 'Low Hanging Fruit'. Extract the read-only Catalogue and Search capabilities first. This builds confidence and proves the Strangler Fig pattern without touching transactional data.
- **New Service**: Build 'Catalogue Service' that reads from a replicated Postgres (via logical replication) or a dedicated search DB (Elasticsearch).
- **Traffic Shift**: Configure the API Gateway to route `/products` and `/search` requests to the new service.
- **Fallback**: If the service fails, the gateway should immediately reroute to the legacy monolith (circuit breaker).
- **Optimization**: Replace the nightly Lucene rebuild with real-time indexing to instantly reflect price/inventory changes.
6. Extraction 2: Customer Identity and Profile (depends on: 5)
Extract user data handling. This decouples the 'who' from the 'what' (purchases), allowing independent authentication scaling.
- **Account Service**: Move user tables (Login, Profile, Address) to a dedicated service.
- **Session Migration**: Implement a token-passing strategy where the legacy monolith trusts tokens generated by the new Identity Service.
- **Read-Through Cache**: The legacy monolith should stop querying the user table directly; instead, it fetches user details from the Identity Service via an internal REST call or cached event.
- **Rollback**: Keep a 'sync-back' script to ensure if users are created in the new service, the legacy DB knows about them during the transition period.
7. Database Decoupling: The 'Anti-Corruption' Layer (depends on: 3, 5)
The most dangerous step. Breaking the 1.2TB DB entanglement requires intercepting the stored procedures. We stop writing to the shared DB from new services.
- **CDC Implementation**: Deploy Debezium to capture Postgres Write-Ahead Logs (WAL) into Kafka. This allows new services to be notified when the monolith updates data.
- **Outbox Pattern**: Refactor the monolith code so that when it writes to the DB, it also writes a 'domain event' to an internal Outbox table, which Debezium then publishes.
- **Read-Only Replicas**: Force new services to read from read-only replicas of the legacy DB to prevent them from causing lock contention on the master.
8. Extraction 3: Inventory and Fulfillment Interface (depends on: 7)
Move the inventory logic out. This separates the 'Stock' truth from the 'Order' truth, preparing for the complex checkout.
- **Inventory Service**: Create a service to hold the 'Single Source of Truth' for current stock levels.
- **Legacy Integration**: The monolith's checkout flow must now ask the Inventory Service to 'Reserve Stock' before processing payment.
- **Warehouse Sync**: Move the 15-minute file exchange logic into this service, isolating the legacy code from warehouse connectivity issues.
- **Concurrency Handling**: Implement optimistic locking in this service to handle high-concurrency 'reserve' requests during sales.
9. Extraction 4: Pricing and Promotions (The 'Black Box') (depends on: 8)
Extract the 200,000 LOC pricing engine. Do not rewrite the logic yet; wrap it. This is a 'Strangler Fig' step, not a refactoring step.
- **Encapsulation**: Move the existing pricing code (and its dependencies) into a new Spring Boot project called 'Pricing Service'.
- **Dependency Injection**: Replace direct DB access within the pricing logic with interfaces that call the Catalogue and Customer services via API.
- **Performance Parity**: Ensure the latency added by moving pricing to a separate network call is negligible (<50ms). Cache aggressively at the service level.
- **Validation**: Use the Golden Master (S4) to replay all historical orders and verify the new service returns the exact same price down to the cent.
10. Extraction 5: Checkout Orchestrator (Saga Pattern) (depends on: 9)
Replace the monolithic transaction with a distributed saga. This is the final piece of the transactional flow.
- **Orchestrator**: Build a lightweight service that coordinates the 'Checkout' process.
- **Saga Logic**: When an order is placed: 1. Call Pricing Service. 2. Call Inventory Service (Reserve). 3. Call Payment Gateway (External). 4. Call Order Service (Create).
- **Compensation**: If step 4 fails, the Orchestrator triggers 'Cancel Reserve' on the Inventory Service and 'Void' on the Payment Gateway.
- **Legacy Cutoff**: The monolith's 'Checkout' screen is replaced by a frontend form that calls this Orchestrator API.
11. Final Monolith Decomposition and Clean-up (depends on: 10)
At this stage, the monolith is hollowed out, containing mostly code that is called by the new services or legacy admin functions.
- **Admin Panel**: Move back-office functionality (Order management, Refunds) into a 'Management Service' that reads from the new event streams.
- **Code Deletion**: Delete the code for the extracted domains (Pricing, Search, Cart) from the monolith repository to enforce boundaries.
- **Database Cleanup**: Drop the tables owned by new services from the legacy monolith database.
- **Performance Tuning**: Optimize the remaining monolith for the only things it does: serving legacy redirects and perhaps a few 'orphaned' modules.
12. Peak Season Stress Test and Handover (depends on: 11)
Prepare for the high-volume events in Jan/July. Validate the new architecture holds under pressure.
- **Chaos Engineering**: Randomly kill the Search or Inventory services and verify the site degrades gracefully (e.g., 'Search temporarily unavailable') without crashing the checkout.
- **Load Testing**: Simulate 12x peak traffic using tools like Gatling/JMeter against the new APIs.
- **Runbooks**: Finalize operational playbooks for every team. Who owns what? How to restart a dead service? How to fallback to the monolith if the database fails?
Note on proposal 1: Excellent technical granularity but dangerously optimistic on the timeline of the Pricing extraction relative to peak seasons.
Adopted: Step 14: Adopted the 'Extract As-Is' (Black Box) strategy for the 200k LOC pricing module to mitigate rewrite risk, which was a superior approach to refactoring during migration.
Adopted: Step 1: Adopted the explicit 'Peak-Season Window Planning' to ensure changes don't hit the Jan/July freeze periods.
Rejected: Step 15: Rejected the idea of 'Phase 2 Refactoring' of pricing rules within the same 12-month plan; this adds unnecessary risk. Refactoring should happen *after* the migration is stable and the pressure is off.
Rejected: Step 9: Extracting 'Search/Catalogue' first is good, but their Step 9 dependencies assumed 'Deployment Pipeline' (Step 7) was fully robust. In reality, you must build the pipeline *before* attempting any extraction, which is why my S3 precedes all extractions.
Note on proposal 2: A solid high-level overview that correctly identifies the Strangler Fig pattern, but it underestimates the complexity of the Database decomposition.
Adopted: Step 3: Adopted the concept of the 'Strangler Fig Facade' at the API Gateway level as the central control point for the migration.
Adopted: Step 13: Adopted the 'Stored Procedure Refactoring' requirement, but moved it to be an implicit part of the 'Anti-Corruption Layer' (S7) strategy rather than a standalone step.
Rejected: Step 12: Rejected extracting Pricing *after* Order Management. If Pricing is a dependency of Order/Checkout, it must be extracted *before* Checkout to avoid calling back into the monolith for critical path logic.
Rejected: Step 7: Rejected 'Inventory Service' as the 7th step. Inventory is a critical dependency for Checkout. It should be extracted (S8) immediately before Checkout (S10) to ensure the reservation logic is ready for the distributed transaction.
Note on proposal 3: The strongest of the three proposals. It accurately reflects the 'Golden Master' strategy and the specific ordering required to handle the monolith's tight coupling.
Adopted: Step 4: Adopted the 'Golden Master' / 'Shadow Traffic' approach for testing. This is the only way to guarantee the pricing engine didn't break.
Adopted: Step 7: Adopted the explicit 'Event Storming' and 'Dependency Matrix' creation as a prerequisite to starting the build.
Rejected: Step 3: Rejected the 'Transaction Outbox' implementation *before* the 'Anti-Corruption' layer is established. You should first ensure you can intercept reads (S7), then establish writes (Outbox), as writes are higher risk.
Rejected: Step 9: Rejected the idea of moving the 'Back-office' (Management) last. It should be migrated alongside Orders (S10) or immediately after, as back-office staff need to manage the new orders as they flow in.
Step-level differences computed by the tool:
Proposal 1 vs the previous-round proposal it resembles most (deepseek-flash_refine_2): 8 steps kept, added ['Program Setup, Scope Ladder, Organizational Model, and Peak-Safe Calendar', 'Pricing Module: Rules Catalog and Golden-Master Characterization (Parallel with Data Platform)', 'Extract Returns: Low-Stakes Proof of Four-Stage Playbook', 'Extract Inventory: Warehouse Sync Improvement and Reservation Semantics', 'Extract Cart: Stateful Session Service', 'Extract Pricing as Black Box Using Golden-Master Validation', 'Extract Payment: PCI-Strict Regime and Provider-by-Provider Cutover', 'Extract Orders: Event-Sourced Record of Truth', 'Extract Checkout: Distributed Saga Orchestration (Highest Risk)', 'Chaos Engineering, Resilience Testing, and Pre-Peak Validation', 'Monolith Decommissioning and Steady-State Operations', 'Peak Season Validation and Post-Peak Stabilization'], removed ['Program setup, peak-aware calendar, rollback charter and scope ladder', 'Split the deployment unit and retire the 30-minute maintenance window', 'Extract Returns as the first write-path and own-database proof', 'Extract Inventory and replace the 15-minute warehouse file exchange', 'Extract Cart', 'Extract Pricing and Promotions as an unchanged black box', 'Extract Payment under a stricter regime than anything else', 'Extract Order Management with an explicit state machine', 'Compose Checkout from independent services using a saga', 'Decommission the monolith core and harden for the second peak']
Proposal 2 vs the previous-round proposal it resembles most (deepseek-flash_refine_2): 15 steps kept, added ['Calendar-first charter, scope ladder and peak-readiness protocol', 'Keep the checkout transaction in the monolith for the first peak, and decide on the saga afterwards', 'Decommission the extracted modules, validate the second peak, write the exit report'], removed ['Program setup, peak-aware calendar, rollback charter and scope ladder', 'Compose Checkout from independent services using a saga', 'Decommission the monolith core and harden for the second peak']
Proposal 3 vs the previous-round proposal it resembles most (claudeHaiku4.5_refine_1): 5 steps kept, added ['Program Governance, Peak Calendar, and Scope Ladder', 'Data Foundation: CDC, Outbox Pattern, and Transactional Events', 'Architectural Decoupling: Table Ownership and Anti-Corruption Layer', 'Characterization Test Harness: The Golden Master', 'First Extraction Pilot: Catalogue and Search (Read-Heavy)', 'Third Extraction: Customer Profile and Identity', 'Core Transactional Extraction: Orders and Order Management', 'Checkout Orchestration and Saga Implementation', 'Payment Provider Integration Service', 'Return and Refund Workflow Extraction', 'Operational Handover and Autonomous Team Setup'], removed ['Strangler Pattern Setup: API Gateway, Feature Flags, and Service Mesh', 'Domain Analysis and Service Boundary Definition via Event Storming', 'Peak Season Protection Framework and Change Freeze Calendar', 'Test Coverage Improvement: Target 70% for Extract-Candidate Modules', 'Change Data Capture and Event-Driven Data Sync Infrastructure', 'Search and Catalogue Service Extraction: Read-Heavy Pilot Service', 'Customer and Loyalty Service Extraction: Identity Decoupling', 'Saga Pattern Framework and Distributed Transaction Orchestration', 'Payment Service Extraction: PCI-Scoped and Secure', 'Orders Service Extraction: Orchestrator for Checkout and Fulfillment', 'Cart Service Extraction: Stateful Session Management', 'Pricing Service Extraction: Black Box Wrapping and Golden Master Validation', 'Returns Service Extraction and Order Lifecycle Completion', 'Load Testing and Peak Capacity Validation Across Full System', 'Team Reorganization and Independent Deployment Readiness']
Origin of the steps of the new proposals, matched by title by the tool (evidence for "taken"; ideas can also travel without a matching title):
Proposal 1: 4 of its 20 steps match its own previous version, 8 are new; steps 2, 3, 4, 6, 7, 11, 17 resemble steps 2, 3, 4, 6, 7, 11, 17 of proposal 2; step 16 resembles step 10 of proposal 3
Proposal 2: 15 of its 18 steps match its own previous version, 3 are new
Proposal 3: 4 of its 16 steps match its own previous version, 6 are new; steps 2, 7, 9, 14, 15 resemble steps 1, 9, 5, 20, 17 of proposal 1; step 1 resembles step 1 of proposal 2
PROPOSALS OF ROUND 2 (to assess):
--- PROPOSAL 1 (agent claudeHaiku4.5_refine_1, anthropic/claude-haiku-4-5) ---
Estimated complexity: high
Success metrics:
- **Zero unplanned downtime**: 100% availability throughout 12-month migration (excluding planned 30-min blue-green deployments); no production incidents attributable to migration architecture
- **Peak seasons protected**: January and July peaks (480k orders/day) sustain zero degradation caused by migration; checkout p99 ≤ 5 seconds, payment authorization ≤ 2 seconds, error rate ≤ 0.5%, no queue backlog > 5 minutes
- **Independent deployability**: All eight services independently deployable by month 12; each team releases on own cadence (weekly or faster) with zero cross-team deployment coordination; 100% of service releases verified rollback-capable in < 30 minutes
- **Rollback-proven**: Every production increment has rehearsed, documented, tested rollback path (expand/contract migrations, feature flags, reverse CDC); monthly chaos game days validate rollback procedures; zero increments reach production without passing rollback gate
- **Data consistency**: Hourly reconciliation shows < 0.001% row-count and checksum discrepancy between service databases and monolith (pre-decommissioning); zero business-invariant violations (no duplicate orders, no lost payments, no inventory oversells)
- **Pricing correctness**: 100% agreement between new Pricing service and golden-master corpus across 1M+ historical requests covering all 8 countries, 3 currencies, 4 languages, all promotion types; zero pricing errors post-cutover
- **Search freshness**: Product availability reflects in search within < 60 seconds of inventory change (vs. nightly rebuild); search latency p95 unchanged or improved at peak load
- **Warehouse sync improvement**: Inventory synchronization lag reduced from 15 minutes to < 2 minutes end-to-end; 100% of daily warehouse updates processed; no missed sync cycles during migration
- **Payment processing**: Zero regressions with all three payment providers; fraud detection active and effective; PCI-DSS compliance maintained; idempotency prevents duplicate charges; payment success rate ≥ 99.5% at peak
- **Back-office operations unaffected**: All 300 staff seamlessly using service APIs; service aggregation endpoints maintain p95 latency ≤ 500 ms; bulk operations (refunds, order status updates) complete within SLA
- **Test coverage for services**: All newly written service code reaches 80%+ line coverage; golden master validates 100% of public API contracts before production traffic; contract tests (Pact) prevent breaking changes between services
- **Peak-readiness gate passed**: Six weeks before each peak (mid-November, mid-May), gate published showing 12x load test results, capacity headroom, rollback rehearsal duration, and SLO status; failed gate defers work; evidence published publicly
- **Team independence by month 12**: Five teams deployed independently; each owns service codebase, pipeline, database schema, on-call rotation, SLOs; no cross-team pull requests blocking releases; internal developer platform (golden-path templates, self-service deployments) adopted by all teams
- **Scope ladder completed**: Rungs 1–6 reached by month 12 (or deliberately stopped at rung boundary with documented justification); all services proven at peak; monolith reduced to < 5% or decommissioned
- **Calendar adherence**: No major extractions or refactors during freeze windows (Dec 1–Jan 15, June 1–July 15); all production increments land in open windows with minimum 4-week soak before freeze; timeline published and adhered to
- **Event-driven architecture validated**: Kafka message broker handles 480k+ messages/day at peak; no message loss, no ordering violations; outbox pattern ensures every domain event persists atomically
- **Fallback capacity maintained**: Monolith rollback path kept warm and functional (receiving live traffic or ready-to-receive via feature flag) until each service survives one full peak; no service extracted without proven rollback capability
Steps (20):
1. Program Setup, Scope Ladder, Organizational Model, and Peak-Safe Calendar
Establishes the governance framework and constraints that all later work obeys. The calendar is the binding constraint—January and July peaks must not be put at risk—so it is decided first, before any technical choices.
**Inception and Baselines**: Run a two-week inception to establish current state: build time, deployment lead time, change failure rate, MTTR per team, module-change frequency, database load profiles (all measurable, not asserted).
**Calendar and Freeze Windows**: Declare hard freezes from December 1–January 15 and June 1–July 15; only rollback-enabling and hardening changes allowed during freezes. Confirm two open delivery windows per year (February–May and August–November); all migration work must fit these windows. No change on checkout path lands within four weeks of a freeze.
**Scope Ladder**: Define ranked rungs 1–6 that deliver the core objective; rungs 7+ are optional. Slippage means stopping at a rung boundary, never mid-increment. Rungs: 1. Platform ready. 2. Search extracted and proven. 3. Returns and Inventory proven at low stakes. 4. Payment and Orders stable. 5. Checkout orchestration live and soaking. 6. Back-office migrated, monolith core reduced.
**Organizational Model**: Define service-aligned teams (Search, Orders, Inventory, Payments, Customer, Fulfillment) with clear ownership, on-call rotations, and SLOs per service. Each team owns codebase, pipeline, database schema, and incidents by month 6. Transition plan: teams split duties (monolith maintenance + service) until month 3, then shift to service-primary by month 6.
**Rollback Charter**: Every increment ships an expand/contract database change, a feature-flag kill switch, and a recorded game-day rehearsal. No go-live without tested rollback in < 30 minutes.
**Peak-Readiness Gate**: Define gate to run six weeks before each peak (mid-November, mid-May): 12x load test, capacity headroom check, rollback rehearsal, error-budget review. Gate is pass/fail; failed gate defers work to next window.
**Capacity Budget**: Allocate 40–50% of five teams' capacity for migration; staff scope ladder to fit capacity, not to fill the year. Create migration enablement squad of six rotating engineers to own platform, shared cuts, and risky data work.
2. Executable Architecture Map, Table Ownership, and Boundary Enforcement (depends on: 1)
Produces an architecture map that the build itself enforces. Five teams in one repo will silently re-couple anything separated if not policed, so enforcement is embedded in the map.
**Real Coupling via Tracing**: Instrument monolith with distributed tracing; let it run four weeks to capture real call paths—static imports miss true coupling.
**Table Ownership Matrix**: Parse every SQL statement, ORM mapping, and stored procedure; cross-check against database query logs. Build table-to-module and query-to-module map. Assign every 350 table to exactly one owning module; tables nobody can own are 'contested' and scheduled into data work (Step 7).
**Scoring and Extraction Sequence**: Score each candidate service on coupling, transactional risk, change frequency, and peak-path criticality. This ranking (not intuition) drives extraction order.
**Enforcement via Automation**: Add ArchUnit rules to CI to fail builds on new cross-module Java dependencies (existing violations frozen in baseline that may only shrink). Add SQL linter to CI to fail on cross-module joins and cross-module writes (same shrinking baseline). Violations tracked weekly in architecture review.
**Stored Procedure Audit**: Inventory all stored procedures; attribute to owning module; plan move into module code or leave as module-private function. No stored procedure may touch two modules' tables post-extraction.
**Architecture Decision Records**: Publish target service list, owning team per service, and reasoning as ADRs.
**Mid-Program Review**: Hold review at month 6 to re-rank scope ladder using what the map actually revealed. This is the one planned re-planning point of the program.
3. Delivery Platform: Per-Service Pipelines, Gateway, Feature Flags, and Environments (depends on: 1, 2)
Builds the delivery and traffic machinery that makes every later step reversible. No service is extracted until its team can deploy, flag, and route independently.
**Kubernetes and Namespaces**: Extend platform on Kubernetes (or existing container platform) with one namespace per service, quotas, and autoscaling sized for 12x peak (480k orders/day). Establish dev/staging/prod with strict resource isolation.
**API Gateway**: Deploy API gateway (Kong, AWS ALB) in front of monolith as strangler entry point. Storefront, mobile app, and back-office traffic flow through gateway from day one, even while routing everything to monolith. Gateway enforces rate limiting, bulkheads, timeouts, and circuit breakers.
**Feature-Flag Service**: Deploy centralized feature-flag system (LaunchDarkly, Unleash). Require every new call path to be flag-guarded. Flags are the primary rollback instrument; changes to traffic routing require no code deployment.
**Per-Module CI/CD Pipeline**: Give every module its own independent CI/CD pipeline and environment. Monolith keeps current pipeline for hotfixes until Step 5 replaces it. Pipeline includes automated security scanning, performance baselines, and contract-test gates.
**Secrets and Configuration**: Introduce secrets management (Vault) and per-environment configuration. Behavioral changes require no monolith redeploy.
**Golden-Path Templates**: Define reusable templates for new services: build layout, Dockerfile, pipeline stages, observability instrumentation, health checks, feature-flag integration, database migration tool. Extraction starts from template, not blank page.
**Permanent Environments**: Reserve two full-size environments: (1) production-like soak environment for multi-week stability validation, (2) load-test environment capable of 12x traffic generation against production-shaped data (8 countries, 3 currencies, 4 languages, realistic product catalog).
4. Observability, Business SLOs, Error Budgets, and Automated Rollback Controller (depends on: 3)
Makes the system observable so canaries are judged automatically and reverted without human guessing. This is the prerequisite for rollback promises in all later steps.
**Observability Foundation**: Deploy centralized logging (ELK/Loki), metrics (Prometheus/Grafana), and distributed tracing (Jaeger) with trace correlation working across gateway, monolith, and every new service from day one.
**Blind-Spot Instrumentation**: Instrument monolith's unmeasured aspects: query latency by module, connection-pool saturation, Lucene rebuild duration, warehouse file-exchange lag, stored procedure execution time, lock contention.
**Business SLOs**: Define SLOs on business outcomes, not infrastructure:
- Checkout success rate ≥ 99.5%
- Order confirmation latency p99 ≤ 5 seconds at baseline (40k orders/day) and peak (480k orders/day)
- Search result latency p95 ≤ 1 second
- Payment authorization latency ≤ 2 seconds
- Price computation latency ≤ 200 ms
- Warehouse sync freshness ≤ 2 minutes end-to-end (vs. current 15 minutes)
- Cross-module data consistency: hourly reconciliation shows < 0.001% row-count discrepancy
**Error Budget and Rollback Policy**: Attach error budget to each SLO. When a service burns budget (or latency diverges > threshold during canary), its rollout stops automatically and flags revert without negotiation. Document policy explicitly; use during peaks without exception.
**Automated Rollback Controller**: Build system that monitors error rate and latency divergence during canary. On breach, gateway shifts traffic back and flags disable automatically. Fallback requires no human intervention. Test this automation in monthly game days.
**Dashboards**: Create per-service dashboards readable by tired engineers at 3 AM (traffic, errors, latency p50/p95/p99, database load). Create program dashboard showing progress against scope ladder, rung by rung.
5. Pricing Module: Rules Catalog and Golden-Master Characterization (Parallel with Data Platform) (depends on: 1, 2)
Catalog the 200k LOC pricing engine behavior before any extraction attempt. This is the foundational risk mitigation for the most complex module; it runs in parallel with data platform work (Step 7) because it is independent of infrastructure.
**Rules Discovery and Documentation**: Analyze and document all pricing rules in scope: country-specific logic (8 countries), currency handling (3 currencies), promotional rules, seasonal pricing, bulk discounts, loyalty point applications, regional variations. Create a living rules inventory.
**Historical Request Corpus**: Capture at least 1 million real historical pricing requests from production logs, covering all 8 countries, 3 currencies, 4 languages, all promotion types discoverable, edge cases, peak-season variations. Record exact inputs and outputs.
**Golden-Master Characterization Suite**: Build automated harness to replay corpus against monolith, capturing deterministic responses. This suite is the 'golden master': any new pricing service must match 100% of outputs. Suite becomes the automated gate for pricing extraction (Step 14).
**Test Data Expansion**: Supplement historical data with synthetic edge cases: multi-currency conversions, minimum purchase thresholds, conflicting promotions, time-based seasonal rules, inventory-driven pricing, customer-segment overrides.
**Dependency Mapping**: Explicitly document which customer attributes, product attributes, inventory levels, time-based factors, and external parameters affect pricing. Identify all cross-module dependencies that pricing currently reads from monolith (e.g., customer loyalty status from Customer module, product hierarchy from Catalogue module).
**Baseline Validation**: Run golden master against monolith to establish baseline passing rate. Document any non-deterministic behavior or race conditions found. This baseline is locked; no drift allowed during migration.
**CI Gate Definition**: Define hard rule: pricing service extraction cannot proceed until characterization tests pass 100% against both monolith and new service. Any divergence blocks ramp. This gate is not negotiable.
6. Seam-Level Verification: Golden Master, Contracts, Shadow Diffing, and Reconciliation (depends on: 2, 3)
Replaces impossible goal of blanket test coverage with verification exactly at the cut point. A 2M-line monolith cannot reach 70% coverage in a year; a service boundary can be verified to very high standard in weeks.
**Characterization Harness for All Services**: Build framework to record real production requests (anonymizing PII) and replay against monolith. Capture full responses as golden master. Every extracted service must pass golden master on its public API before taking live traffic. Output a diff report, not pass/fail.
**Consumer-Driven Contracts (Pact)**: Require contracts between monolith and each new service, and between services themselves. A change on one side breaks a build instead of waiting for production. Contracts versioned; breaking changes trigger explicit communication plan.
**Shadow Traffic and Response Diffing**: Mirror live requests to new service; compare responses field by field (not just status codes). Measure divergence rate continuously. Gate traffic ramp on divergence < 0.01% for 48 hours.
**Per-Module Data Reconciliation**: Build data reconciliation as first-class test, not afterthought. Compare row counts, checksums, and business invariants on hourly schedule. Owner assigned; alert threshold set. Reconciliation runs continuously during transition period (Stages A–C of cutover playbook).
**Synthetic Canary Transactions**: Implement real checkout, return, and search transactions executing every few minutes. Alert on functional regression before customers notice. Include multi-country, multi-currency variations.
**Explicit Non-Goal**: Do not pursue blanket line coverage of monolith. Track coverage only for newly written service code, target 80%. Seam-level verification replaces this impossible goal.
7. Data Platform: Schema Ownership, Join Elimination, CDC, Transactional Outbox, and Four-Stage Cutover Playbook (depends on: 2, 3)
The hardest and most under-specified part of most migrations. This work is independent of service extraction, so it starts in month 1 and runs in parallel. It is the foundation for reversible data transitions.
**Database-Enforced Ownership**: Assign every PostgreSQL table to exactly one module. Create one role per module, able to write only its own schema and to read others only through defined views. Database rejects cross-schema writes at the engine level, not by convention. Test this enforcement in CI.
**Stored Procedure Refactoring**: Inventory every stored procedure, attribute it to owning module. Either move logic into that module's application code or leave as module-private database function. After extraction, no stored procedure may touch two modules' tables.
**Cross-Module Join Elimination**: Eliminate cross-module joins one at a time, replacing each with an API call (preferred during cutover), an event-fed materialized read model, or a duplicated read-only projection. Track count per module; drive to zero before that module is extracted.
**Change Data Capture (CDC)**: Deploy Debezium reading PostgreSQL WAL into Kafka. This publishes monolith domain events with zero application change—lowest-risk start possible. Configure per-table CDC; test at peak load (480k events/day during 12x peak).
**Transactional Outbox Pattern**: For all new services, add outbox table. When service writes business state, it writes domain event atomically in same transaction. Outbox relay publishes to Kafka, ensuring no event loss. Implement poison-pill handling for failed publishes.
**Four-Stage Cutover Playbook (Reusable)**: Define one playbook applied identically every service extraction:
- **Stage A** (Shadow-Read): Service owns schema logically, reads from CDC into its own store, serves shadow traffic only. Monolith remains system of record; no cutover yet.
- **Stage B** (Read Cutover): Reads cut over to new service via flag. Monolith stays system of record via reverse-CDC replication. Rollback is flag flip + reconciliation pass.
- **Stage C** (Write Cutover): Writes cut over to new service. Monolith tables become read-only replicas fed by reverse CDC from service. Rollback is configuration change (flip sync direction) + reconciliation, not data restore.
- **Stage D** (Deletion): Old tables and dead code dropped only after module has survived one full peak (January or July) or four clean weeks, whichever is longer. Maintain 90-day read-only archive of old tables for regulatory retention and emergency queries.
**Reconciliation Service**: Build now (not later) so every cutover has objective consistency check. Compare row counts, business-invariant checksums, monetary totals hourly. Owner assigned; thresholds set. Mismatch is immediate rollback signal.
**Storage Migration Timeline**: New services start on existing cluster with own schemas. Physical database split (move to separate cluster) happens only once module is stable and proven at peak. This removes a critical-path blocker and allows parallelization.
8. Extract Catalogue and Search: Read-Heavy Pilot Service (depends on: 5, 6, 7)
First extraction, chosen because it is read-heavy, isolated, and carries no transactional risk. It also pays for itself: replacing nightly Lucene rebuild with real-time indexing is a visible business win that buys political cover for harder cuts.
**New Catalogue Service**: Create service owning product, category, media, and attributes tables. Build search API using Elasticsearch/OpenSearch with real-time indexing.
**CDC Feed**: Subscribe to CDC stream from monolith. ProductUpdated, PriceChanged, InventoryUpdated events trigger real-time search index refresh. Product availability reflects in search within < 60 seconds of change (vs. nightly rebuild).
**Shadow Traffic and Diff Validation**: Route requests through gateway behind feature flag. Run shadow mode: send requests to both monolith Lucene and new Search service; compare result sets field by field. Measure divergence; require < 0.01% for 48 hours before traffic ramp.
**Gradual Traffic Ramp**: 1% → 5% → 25% → 50% → 100% using feature flags and canary deployments. Rollback controller monitors latency and error rates; reverts flag if breach. Keep old Lucene index warm for two weeks post-cutover as rollback target.
**Mobile App Verification**: Verify mobile app behavior explicitly; it hits same endpoints. Test session persistence, offline search cache behavior, and app version compatibility during ramp.
**Four-Stage Playbook**: Execute Stages A–D as defined in Step 7. Stage A (shadow) lasts 1 week minimum. Stage B (read cutover) lasts 2 weeks. Stage C does not apply (reads only). Stage D (cleanup) after one peak or four weeks.
**Soak Period**: Land this extraction in open delivery window; soak at least four weeks before freeze (Dec 1 or June 1). No extraction reaches production less than four weeks before a freeze.
9. Extract Returns: Low-Stakes Proof of Four-Stage Playbook (depends on: 5, 6, 7)
Second extraction and first write-path proof. Returns is chosen because it is off peak-critical path, has modest coupling, and exercises full four-stage playbook at low risk. Primary output is a proven, reusable procedure, not just one service.
**Returns Service**: Build with own schema. Consume order and customer events rather than joining their tables. Implement return state machine: Requested → Approved → Shipped → Received → Refunded.
**Full Four-Stage Execution**: Apply Stages A–D end-to-end with explicit recorded game day validating each stage rollback path. Stage A (shadow reads) for 1 week. Stage B (read cutover) for 2 weeks. Stage C (write cutover) with reverse CDC. Stage D (cleanup) after one peak or four weeks.
**Rollback Rehearsal**: Before write cutover, execute full game day: simulate service failure mid-cutover, trigger rollback (reverse CDC, flag flip, reconciliation), verify all data consistent, re-run golden master, confirm back-office queries still work. Record this session; play back monthly.
**Back-Office Screens**: Keep back-office returns screens on monolith for now (staff workflow untouched). Returns service is API-only; back-office integration comes later (Step 18).
**Friction Point Capture**: Record every operational friction, process gap, and test hole discovered during extraction. Update playbook from learnings. This step is as much about process validation as about extracting Returns.
**Soak and Timing**: Execute in open window; soak returns service for minimum four weeks before any freeze. Gate to proceeding to Inventory (Step 10) is successful four-week soak with zero rollbacks and full reconciliation agreement.
10. Extract Inventory: Warehouse Sync Improvement and Reservation Semantics (depends on: 5, 6, 7)
Removes one of sharpest coupling points (15-minute file-exchange lag) and unblocks checkout work. Inventory runs in parallel with returns because it couples monolith to external warehouse system, not to other modules.
**Inventory Service**: Ingest warehouse feed directly (SFTP/API) instead of monolith polling. Design reservation semantics now: Reserve (place hold), Confirm (finalize after order), Release (cancel reservation on timeout/failure), with explicit timeout windows. Own stock levels and reservations per product per location.
**Parallel Feeds During Transition**: Run new ingest in parallel with legacy 15-minute feed. Reconcile hourly until both agree. This validates the new ingest does not miss updates or duplicate changes.
**Monolith Inventory Tables as Projection**: Keep monolith's inventory tables as read-only replicas fed by CDC from new service during Stage C (write cutover). Cart and checkout continue calling monolith queries unchanged during cutover; no checkout changes yet.
**Four-Stage Execution**: Apply Stages A–D. Stage A (shadow ingests and reads) for 2 weeks (must survive two 15-minute sync windows and validate no drift). Stage B (read cutover) for 2 weeks. Stage C (write cutover) with reverse CDC. Stage D (cleanup) after one peak.
**Peak-Load Testing**: Load-test inventory ingest at 12x (400k SKU updates/day during peak). Warehouse feed schedule and sales peaks do not always align; test worst-case concurrency. Validate no reservation deadlocks, no stock over-sells.
**Cutover Order**: Inventory read cutover must complete before Cart extraction (Step 13) to avoid monolith checkout calling new Inventory service via internal API during transition.
**Soak and Gate**: Soak minimum four weeks before freeze. Gate to proceeding to Customer (Step 11) is four-week soak with zero reconciliation mismatches and warehouse feed lag improved to < 2 minutes.
11. Extract Customer Accounts and Loyalty: Conservative Authentication Strategy (depends on: 9, 10)
Extracts customer identity, profile, and loyalty programs. Authentication is deliberately placed late and guarded hardest because auth failures derail e-commerce migrations most often.
**Customer Service**: Own profile, address, and loyalty tables. Implement country-specific loyalty rules (8 countries, different point accrual rates) as data-driven rules where possible, code where not. Design API: GetCustomer, UpdateProfile, GetLoyaltyBalance, RedeemPoints, AccruePoints.
**Authentication Strategy Phase 1**: Keep authentication (login) in monolith for now. Customer service exposes only data APIs; token issuance remains monolith's responsibility. This delays risky auth cutover; less risk to peak season.
**Distributed Session Handling**: Introduce Redis-backed distributed sessions. Services can verify customer identity without querying monolith database. Implement token-validation API so services can verify bearer tokens without round-tripping to monolith.
**Data Cutover**: Execute four-stage playbook. Stage A (shadow reads) for 1 week. Stage B (read cutover) for 2 weeks. Stage C (write cutover) for new customers, address updates, loyalty accrual. Stage D (cleanup) after one peak.
**Golden Master for All Countries**: Golden master captures customer queries across all 8 countries, all 4 languages, and all loyalty-rule variations. Shadow-traffic diff must show < 0.01% divergence before read cutover.
**Mobile App Session Behavior**: Test mobile app's long-lived sessions explicitly; storefront does not hold sessions same way. Validate token refresh, session timeout, and app version compatibility during cutover.
**Loyalty Accrual Last**: Move loyalty point accrual and redemption last within this step (Stage C final substep). Loyalty error is customer-visible financial error, not technical incident; guard hardest.
**Soak and Gate**: Soak minimum four weeks. Gate to proceeding to Cart (Step 13) is successful loyalty accrual cutover with zero customer complaints and full reconciliation agreement.
12. Extract Cart: Stateful Session Service (depends on: 6, 7, 10, 11)
Extract shopping cart, which is stateful and sits directly in front of checkout. Extracted before Pricing and Checkout because both depend on stable Cart boundary.
**Cart Service on Redis**: Build on Redis (or PostgreSQL with session affinity) for session and line-item state. Validate products and inventory through service API calls rather than direct database joins. Design API: AddItem, RemoveItem, UpdateQuantity, GetCart, ApplyCoupon, ClearCart.
**Idempotent Operations**: Every cart operation is idempotent. Retried add during peak does not duplicate line item. Retried remove is safe. Implement via unique constraint on (session, sku) or idempotency-key header.
**Monolith Cart Tables as Projection**: Keep monolith's cart tables as read-only projections fed by CDC from Cart service. Back-office screens continue reading old cart tables for abandoned-cart analytics (not yet migrated to service APIs in this step).
**Four-Stage Execution**: Apply Stages A–D. Stage A (shadow reads) for 1 week. Stage B (read cutover) for 2 weeks (use feature flag; gradual ramp 10% → 50% → 100%). Stage C (write cutover to service); Stage D after one peak.
**Business Metric Monitoring**: Cart latency surfaces as lost revenue (abandonment), not just error logs. Track cart abandonment rate and add-to-cart latency as primary success metrics during ramp.
**Anonymous vs. Authenticated Carts**: Test both paths separately; they follow different session-tracking mechanisms and fail in different ways. Ensure cart persists across login boundary.
**Soak Before Freeze**: Land in open window; soak minimum four weeks before freeze (Dec 1 or June 1). Gate to proceeding to Pricing (Step 14) is four-week soak with cart abandonment rate unchanged or improved and zero lost transactions.
13. Extract Pricing as Black Box Using Golden-Master Validation (depends on: 5, 6, 7)
Extract 200k LOC pricing logic as-is without rewriting. Rules are not understood by anyone, so wrap and characterize rather than refactor. Rule decomposition deferred to follow-up program in writing.
**Wrap Without Refactor**: Move pricing code into dedicated service, unchanged. Service owns pricing tables post-cutover. Expose single decision API: ComputePrice(customerId, productId, locationId, timestamp, quantityId, loyaltyStatus) → {price, applicablePromotions, taxes, currency}.
**Dependency Injection for Reads**: Refactor pricing's dependencies so it obtains customer data via Customer service API, product data via Catalogue service API, inventory via Inventory service API. No direct cross-module database joins.
**Golden-Master Validation**: Run characterization test suite (built in Step 5) against new service. Require 100% output match on all 1M historical requests across all 8 countries, 3 currencies, 4 languages, all promotion types, edge cases. Any divergence blocks ramp; no exceptions.
**Shadow Mode Duration**: Run shadow traffic against live pricing requests for minimum four weeks, comparing every computed price with monolith. Measure divergence continuously. Divergence > 0.001% blocks ramp.
**Gradual Cutover by Country**: Cut over per-country rather than all-at-once. Start with lowest-revenue country, validate four weeks per country, then ramp to others. Per-country flags allow independent rollback.
**Rollback Path**: Keep monolith's pricing evaluator available and warm as rollback target for at least one full peak (January or July) after cutover. Maintain ability to flip back to monolith pricing via feature flag without data restore.
**Four-Stage Playbook**: Stages A–D applied to pricing tables. Stage A (shadow) 4+ weeks. Stage B (read cutover) 2 weeks per country. Stage C (write cutover) per country. Stage D (cleanup) after one full peak.
**Deferred Refactoring in Writing**: Publish decision that pricing rule decomposition, DSL, and optimization are explicitly deferred to follow-up program after this migration stabilizes. Include this in all project communications and retrospectives.
14. Extract Payment: PCI-Strict Regime and Provider-by-Provider Cutover (depends on: 5, 6, 7)
Extract payment processing with stricter regime than any other service. Mistakes are irreversible and regulatory. Extracted before checkout orchestration because checkout cannot be decomposed without payment boundary.
**Payment Service**: Own integration with three payment providers (tokenization, authorization, capture, refund, provider webhooks). Design API: AuthorizePayment(idempotencyKey, amount, currency, cardToken, customerId) → {authorizationId, status}; CapturePayment(authorizationId); RefundPayment(captureId); HandleWebhook(webhookPayload).
**PCI Scope Reduction**: No raw card data at rest in service. Card data flows directly from client to provider (tokenization); only tokens stored in Payment service. Credentials in secrets management (Vault). No card data in logs or distributed traces.
**Idempotent Operations**: Explicit idempotency-key handling. Every payment request is idempotent; retries at peak are normal and must not double-charge. Implement via idempotency-key deduplication store (Redis with TTL).
**Provider-by-Provider Cutover**: Cut over one provider at a time (start with lowest-volume provider). Stage A (shadow) 2 weeks per provider. Stage B (read cutover, not applicable). Stage C (write cutover) for each provider, maintain fallback to monolith for other providers. Test each provider's decline, timeout, 3-D Secure, and chargeback scenarios explicitly.
**Golden Master Scenarios**: Golden master covers all three providers, all decline reasons, timeouts, partial authorizations, refund scenarios, chargebacks. Shadow traffic compares full payment outcomes (authId, status, amount, timestamp) before any live provider cutover.
**Fraud Detection and 3-D Secure**: These paths are usually least-tested and most visible when broken. Test explicitly; goldne master includes fraud-decline and 3-D Secure flows. Verify fraud rules and thresholds carry over unchanged.
**Fallback Orchestration**: Monolith retains ability to handle payment directly (as fallback) until second peak after Payment service cutover. Checkout can gracefully degrade to old payment path via feature flag if new service fails.
**Four-Stage Playbook**: Stages A–D per provider. Stage C (write) is highest-risk; ensure golden master passes 100% and shadow mode shows zero divergence before each provider cutover. Gate and soak strictly: four weeks minimum before any freeze.
**Soak and Timing**: Land in open window (Feb–May or Aug–Nov). Complete all three providers' Stage C cutover by month 9 to allow checkout orchestration time to soak before freeze.
15. Extract Orders: Event-Sourced Record of Truth (depends on: 9, 13, 14)
Extract order management as authoritative record of order lifecycle. Extracted after Inventory, Pricing, and Payment exist and are stable, because Orders depends on all three.
**Orders Service**: Own order tables and order state machine. Implement explicit state transitions: Pending → Confirmed → Preparing → Shipped → Delivered, with validation blocking invalid transitions. Design API: CreateOrder(cartId, customerId, paymentAuthorizationId), GetOrder(orderId), CancelOrder(orderId), UpdateOrderStatus.
**Event Sourcing**: Record all order state changes as immutable events. Build order state from event log on demand. Audit trail satisfies regulators and fulfillment teams; state can be rebuilt after incidents. Include: OrderCreated, PaymentAuthorized, InventoryReserved, OrderConfirmed, OrderPreparing, OrderShipped, OrderDelivered, OrderCancelled.
**Event Consumption**: Consume events from Payment service (PaymentAuthorized, PaymentFailed), Inventory service (StockReserved, ReservationCancelled), and Returns service (ReturnInitiated, RefundIssued) rather than polling or joining.
**Four-Stage Playbook**: Stages A–D. Stage A (shadow) for 1 week. Stage B (read cutover) for 2 weeks, with gradual flag ramp. Five teams that query orders start reading from Orders service via API. Stage C (write cutover): new orders written to Orders service; monolith order tables become reverse-CDC read-only replicas. Stage D after one peak.
**Reconciliation: Monetary and Row-Count**: Reconcile order counts and monetary totals hourly against monolith throughout transition. Currency totals must match exactly (cent-by-cent); row count discrepancies are immediate rollback. Implement automated reconciliation query; owner assigned; threshold zero.
**Concurrent Order Transitions**: Load-test concurrent order state transitions at 480k/day peak. Order state machine becomes serialization point for distributed system; ensure no race conditions, no duplicate orders, no lost transactions.
**Soak Before Checkout**: Complete Orders cutover (Stages A–C) by month 9. Soak minimum four weeks before freeze. Gate to proceeding to Checkout (Step 16) is four-week soak with zero monetary reconciliation mismatches and zero order duplicates.
16. Extract Checkout: Distributed Saga Orchestration (Highest Risk) (depends on: 12, 13, 14, 15)
Highest-risk extraction, deliberately placed last among transactional work and only after components it orchestrates are individually proven at scale. This step composes independent services into coherent checkout flow.
**Checkout Orchestrator Service**: Build service that coordinates checkout: cart validation, price computation, inventory reservation, payment authorization, order creation. Design as explicit saga with named steps and compensating actions.
**Saga Orchestration**: Implement synchronous saga (single coordinator) or asynchronous (choreography via events), chosen based on latency testing (target checkout p99 < 5 seconds at peak). Synchronous preferred for checkout because customer waits; failure is visible. Steps:
1. Validate cart via Cart service
2. Compute price via Pricing service (cached if < 1 second old)
3. Reserve inventory via Inventory service
4. Authorize payment via Payment service
5. Create order via Orders service
**Compensating Transactions**: For every step, define compensation:
- Step 3 fails: Release inventory reservation
- Step 4 fails: Release inventory reservation, void authorization (if possible)
- Step 5 fails: Release reservation, void authorization, return payment to customer
- Step 2 recomputes and differs: Increase price, reject order; or decrease price, accept at old price (business rules decision, document explicitly)
**Idempotency End-to-End**: Checkout request includes idempotency key (unique per browser session + timestamp). Service deduplicates on this key. Retried checkout cannot double-charge or double-reserve; returns previous result.
**Timeout Handling**: Inventory reservation expires in 15 minutes (configurable). Payment authorization valid for 7 days (provider-specific). Order creation never times out; if hanging, manually investigate. Saga must fail safe to retryable state, never to half-committed order.
**Shadow Traffic Before Live**: Mirror live checkout traffic (100% of checkout requests during business hours) to new orchestration for minimum 2 weeks before any live cutover. Compare full outcomes: order ID, order total, inventory reservations, payment authorization IDs, error messages. Divergence > 0.001% blocks live cutover.
**Live Ramp During Open Window**: Ramp live traffic only during open delivery window (Feb–May or Aug–Nov). Gate and soak strictly: minimum four weeks before freeze. Keep monolith checkout path fully functional and warm (receiving live traffic via feature flag) as rollback target until Checkout service has survived one full peak.
**Peak-Readiness Gate Mandatory**: Hold six-week peak-readiness gate (Step 19) before proceeding to back-office migration (Step 18). Failed gate stops this work immediately and defers to next window.
17. Migrate Back-Office, Storefront, and Mobile Clients to Service APIs (depends on: 16)
Moves 300 back-office staff and client applications off monolith database direct access. Until this step, monolith database remains live dependency even where logic moved.
**Back-Office Screen Refactoring**: Migrate screens table by table. Replace direct SQL with service API calls through gateway. Start with orders (call Orders service), then customers (call Customer service), then inventory (call Inventory service). Build aggregation endpoints: /orders/{id}/full-details calls Orders + Payments + Inventory + Returns services, caches 30 seconds, returns unified response.
**Aggregation Endpoints and Caching**: Services are now call-chain away, not co-located. Back-office latency would suffer without caching. Implement short-lived cache (TTL 30 seconds) for frequently accessed data (customer profiles, recent orders). Graceful degradation: if one service slow, show cached data and alert staff.
**Storefront and Mobile App**: Both hit same endpoints (via gateway). Update storefront (server-rendered) to call service APIs while keeping old path functional behind feature flag; rendering regression becomes flag flip, not rollback. Mobile app points at gateway for migrated endpoints; keep old endpoints alive for un-updated app versions (users do not upgrade on schedule). Implement API versioning: v1 (legacy monolith), v2 (service APIs); clients request version in Accept header.
**API Versioning and Deprecation Windows**: Publish versioning rules: breaking changes trigger major version bump (v2 → v3). Old version supported for minimum 90 days after major release. Client teams must upgrade within window; do not force upgrade. Document deprecation timeline in API spec.
**Load Test Back-Office Concurrency**: Test 300 concurrent staff on top of peak storefront (480k orders/day). New services now carry both loads; autoscaling and database connection pools must handle burst. Simulate realistic staff queries: order searches, customer history, bulk refunds.
**Distributed Tracing for Debugging**: Every back-office request traced across services. Staff can view trace in UI; operations team can see which service was slow. Trace includes: request start, service calls, database queries, cache hits/misses.
**Monitoring and Runbooks**: Create runbooks for common issues: slow customer search (check Customer service load), payment lookup fails (check Payment service), order create fails (check Orders service latency). Link from dashboard to runbook.
**Gate to Monolith Decommissioning**: Back-office must be fully migrated (no direct SQL reads to monolith) before monolith core decommissioning (Step 18). This step completes organizational cutover.
18. Chaos Engineering, Resilience Testing, and Pre-Peak Validation (depends on: 17)
Validates new distributed architecture survives failure scenarios and peak load without cascading collapse. This step is as much about proving state is coherent as about finding failure modes.
**Chaos Game Days**: Scheduled monthly (or before each peak). Kill each service in turn (Search, Inventory, Orders, Payments, etc.); confirm storefront degrades gracefully (e.g., 'Search temporarily unavailable, catalog browsing still available') rather than failing completely. Kill database replicas; verify service continues with read-only or cached data. Kill message broker; verify no events lost and no reordering. Record each game day; publish findings and mitigation actions.
**Peak-Readiness Gate (Before Each Peak)**: Run six weeks before January and July peaks (mid-November, mid-May):
- **12x Load Test**: Generate realistic 480k orders/day traffic against production-shaped data (8 countries, 3 currencies, 4 languages, realistic product hierarchy). Measure checkout p99 < 5 seconds, search p95 < 1 second, payment < 2 seconds.
- **Capacity Headroom**: Confirm all services autoscale to handle 12x baseline. Database connection pools have headroom. Message broker partitions are sufficient. Cache hit rates do not collapse under load.
- **Rollback Rehearsal**: Execute full rollback of most recent service extraction in load-test environment. Measure rollback time; must be < 30 minutes including data reconciliation.
- **Error Budget Review**: Confirm SLO error budgets not burned significantly. If burned, identify culprit and mitigate before peak.
- **Evidence Publication**: Publish load-test results, capacity headroom metrics, rollback time, and SLO status. Gate is pass/fail; failed gate defers peak exposure and triggers root-cause work.
**Full System Load Test**: All services under load simultaneously. Measure inter-service latencies, database load, message broker throughput. Identify bottlenecks: pricing calculations, search queries, payment provider round-trip time, inventory reservations under concurrent access. Tune:
- Database query indexes
- Connection pool sizes
- Caching strategies
- Message broker partitions
- Service autoscaling thresholds
**Failure Mode Analysis**: Identify top 10 single-point-of-failure risks:
1. Payment provider outage → graceful degradation (pre-authorize smaller amounts?)
2. Inventory service down → checkout blocked; mitigation: cache inventory in checkout orchestrator
3. Pricing service down → checkout blocked; mitigation: cache last-known prices
4. Orders service down → checkout blocked; mitigation: queue orders in Kafka, replay when service recovers
5. Database down → all services blocked; mitigation: read-only replicas for queries
6. Message broker down → no events published; mitigation: outbox patterns ensure no event loss
7. API gateway down → all traffic blocked; mitigation: active-active gateway setup (two regions or multiple providers)
8. Warehouse sync delayed → inventory stale; mitigation: alert threshold, manual intervention process
9. Customer service down → login blocked; mitigation: cache tokens, allow anonymous checkout
10. Search service down → browsing blocked; mitigation: fallback to category list without search
For each failure, document mitigation (architectural change or operational procedure), test in chaos game day, and update runbooks.
**Synthetic Transaction Monitoring**: Implement real-world checkout, return, and search transactions executing every five minutes. Alert on failure before customers notice. Include multi-country, multi-currency variations.
**Performance Baseline Documentation**: Document baseline latencies (checkout, search, payment) at baseline load (40k orders/day). Load test must show no regression at peak; improvements accepted. Document these baselines in runbooks for operations team reference.
19. Monolith Decommissioning and Steady-State Operations (depends on: 18)
Safely retire monolith code once all services stable and production-proven. This step is final validation that new architecture is coherent; incomplete decommissioning signals hidden coupling.
**Module-by-Module Cleanup**: Delete extracted service code from monolith only after that service has survived one full peak (January or July, whichever comes first) or four clean weeks post-cutover, whichever is longer. Before deletion:
- Audit dead code: which stored procedures, views, tables, methods are no longer called
- Verify service API is the only interface for data owned by extracted module
- Confirm no service calls back into monolith code
- Delete extracted logic and dependencies
**Database Decommissioning**: Dropped tables are archived (not deleted) for 90 days (regulatory retention and emergency queries). After 90 days, drop and archive to long-term storage. Monolith database shrinks as modules extracted. When monolith becomes shell (mostly unused), decide: keep as fallback or shut down entirely.
**Cross-Module Stored Procedures**: All stored procedures touching multiple modules' tables must be eliminated before monolith shutdown. If any remain, move logic into services or refactor. Document any that cannot be moved; escalate as risk.
**Backup and Recovery Procedures**: Shift from single monolith snapshot to per-service snapshots. Each service team owns backup/recovery for their database. Document recovery procedures: which services recover in which order, which can tolerate data loss vs. which require point-in-time recovery. Test recovery monthly.
**Architectural Decision Records**: Publish final ADRs documenting:
- Why services were split at these boundaries
- What problems each split solved
- What trade-offs were made
- What cross-service communication patterns emerged
- What monitoring and alerting proved most useful
**Operational Runbooks**: Finalize runbooks for each team:
- Incident response: common failure modes, resolution steps, escalation paths
- Deployment procedures: how to deploy service, rollback procedure, expected latency
- On-call procedures: alert thresholds, page-worthy events, war room communication
- Database procedures: backup, restore, schema migrations, connection pool tuning
**Service Ownership Model**: Confirm each of five teams owns one or more services end-to-end:
- Codebase and CI/CD pipeline
- Database schema and migrations
- On-call rotation and SLOs
- Production incidents
- Capacity planning and scaling
No shared ownership; clear escalation paths between teams.
**Team Ramp-Down of Migration Work**: Migration enablement squad (formed in Step 1) transitions into steady-state platform team. Reduce migration velocity; redirect capacity to feature work on services.
**Exit Criteria and Project Close**:
- All rungs 1–6 of scope ladder complete (or deliberately stopped at rung boundary)
- Both peak seasons (January and July) survived without migration-caused incidents
- All services deployed independently by month 12
- Monolith reduced to < 5% of original codebase or decommissioned entirely
- All architectural decisions documented and team alignment confirmed
**Celebrate and Document Lessons**: Publish retrospective capturing:
- What went well: which techniques proved most valuable (golden master? chaos testing? soak periods?)
- What was hard: which services took longer, which risks materialized
- What would change next time
- Which rungs of scope ladder were reached and why work stopped where it did
**Deferred Work**: Explicitly list architectural or optimization work deferred to follow-up programs (e.g., Pricing DSL refactoring, read-write split at database level, multi-region deployment).
20. Peak Season Validation and Post-Peak Stabilization (depends on: 18, 19)
Proves new architecture survives peak and validates migration is truly complete. January and July peaks are the final test; this step verifies readiness and documents learnings.
**Pre-Peak Confirmation**: One week before peak start (Dec 25 for January peak, June 25 for July peak), confirm:
- All peak-readiness gate checks passed
- All services healthy and responding normally
- Database connection pools at capacity
- Cache hit rates normal
- Message broker lag within SLOs
- On-call rotations staffed
- War room communication channels open
**Peak Monitoring**: During peak (480k orders/day sustained for 2–3 weeks), maintain heightened monitoring:
- Every service dashboard visible in central war room
- Latency p99, p95, p50 trending in real time
- Error rate per service alarmed
- Database query performance monitored
- Message broker lag tracked
- Payment success rate watched (fraud filters, authorizations)
- Inventory reservation accuracy validated hourly
**Incident Response**: Any incident < 5 min MTTR automatically escalates to war room. Team lead validates:
- Root cause (service slow? database? payment provider?)
- Impact (customer-visible? checkout blocked? data corruption?)
- Mitigation (rollback flag? scale service? throttle traffic?)
- Recovery (how long to resolve?)
**Post-Peak Retrospectives**: Within one week of peak completion, each service team retrospectives on:
- Peak traffic patterns observed vs. load-test simulations
- Any incidents: root cause, time-to-detect, time-to-recover
- Performance variations: which services scaled, which became bottlenecks
- Data accuracy: any reconciliation mismatches discovered during peak
- Lessons for next peak
**Capacity Planning**: After peak, analyze:
- Database query times at peak: any unexpected slowdowns?
- Service autoscaling: did services scale early enough? were there cascading failures?
- Cache effectiveness: hit rates at peak vs. baseline
- Message broker: any message loss or reordering?
- Payment provider latency: did provider response times increase during peak?
**Final Validation**: Confirm scope ladder rung achieved:
- Rung 6 complete: back-office migrated, monolith core reduced, checkout orchestration stable
- Teams deployed independently during peak (or blocked from deploying due to freeze, which is correct)
- Zero unplanned downtime caused by migration
- All rollback procedures worked in chaos testing; never needed in production
**Program Closure**: Publish final evidence:
- Peak season metrics (order volume, success rate, latency, errors)
- Service-by-service stability (uptime, incidents, MTTR)
- Scope ladder rung reached
- Explicit deferred work list
- Team feedback and lessons learned
**Next Program Planning**: If rung 7+ desired (e.g., Pricing rules DSL refactoring, multi-region deployment), plan as separate 6-month program. Document in writing; do not creep scope into current program.
Note on proposal 2: Proposal 2 provides the strongest foundation: explicit calendar constraints (Dec 1–Jan 15, June 1–July 15 freezes), scope ladder concept, four-stage cutover playbook, and data platform as a distinct critical track that starts in month 1.
Adopted: Step 1 (Program Setup): Adopted calendar and freeze windows (Dec 1–Jan 15, June 1–July 15) wholesale; this is the binding constraint in the brief and Proposal 2 makes it explicit and non-negotiable.
Adopted: Step 2 (Architecture Map): Adopted table-to-module enforcement via ArchUnit and SQL linters; the insight that boundary slippage must be enforced at CI level (not review) is crucial for a five-team monorepo.
Adopted: Step 3 (Delivery Platform): Adopted blue-green deployment and feature-flag kill-switch as primary rollback mechanisms; adopted golden-path templates to accelerate service extraction.
Adopted: Step 6 (Seam Verification): Adopted golden-master characterization harness and explicit policy to not pursue blanket monolith line coverage (80% target for new code only is pragmatic).
Adopted: Step 7 (Data Platform): Adopted four-stage cutover playbook end-to-end; this single reusable framework (Shadow-Read → Read Cutover → Write Cutover → Deletion) is the highest-leverage insight in Proposal 2, eliminating ad-hoc cutover decisions.
Adopted: Step 7 (Reconciliation as First-Class Test): Adopted hourly reconciliation with thresholds and owners; a mismatch is immediate rollback signal, not a ticket. This removes ambiguity about data correctness.
Adopted: Scope Ladder Concept: Adopted the explicit ranked rungs; slippage means stopping at rung boundary, not mid-increment. This is the correct framing for a 12-month constrained program.
Rejected: Service extraction sequence (Steps 8–16): While Proposal 2's order is sound (Search → Returns → Inventory → Customer → Cart → Pricing → Payment → Orders → Checkout), it underemphasizes the foundational work in data platform (Step 7) and pricing characterization (Step 5 in my proposal). Proposal 2 bundles both into step 7 and step 13 implicitly; I separate them as Step 5 (Pricing Rules Catalog, parallel in month 1) and Step 7 (Data Platform) to remove false dependencies and start cataloging pricing rules immediately rather than waiting for platform readiness.
Rejected: Step 1 Organization Aspect: Proposal 2's Step 1 mentions 'set capacity budget' but does not explicitly articulate team restructuring toward service-aligned ownership or clarify when teams transition from business-function teams to stream-aligned (service) teams. This organizational change is substantial and deserves explicit step planning (included in my S1 expansion).
Rejected: Mobile App Versioning Strategy: Proposal 2's Step 17 mentions keeping old endpoints alive for un-updated app versions but lacks detail on API versioning policy, long-lived session handling, and app distribution contingencies. This is a material risk for e-commerce: mobile app users do not upgrade on company schedule, and session mismatches between old and new API can lose carts. I expand this in my S17.
Rejected: Warehouse Sync Improvement Detail: Proposal 2's Step 10 states improving from 15 minutes to < 2 minutes but does not detail parallel ingestion during transition or reconciliation procedure to validate new ingest does not miss updates. I add explicit parallel-feed validation as a transition mechanism in my S10.
Rejected: Chaos Engineering Emphasis**: Proposal 2 mentions chaos testing late (implied in step 4, explicit only in step 18). Resilience testing of critical paths (checkout, payment, inventory) should start earlier and be reinforced multiple times. I elevate chaos engineering to a dedicated step (S18) with explicit game-day schedule and failure-mode analysis before first peak.
Note on proposal 1: Proposal 1 is comprehensive and detail-rich on testing strategy and peak-season protection but creates unnecessary serialization through 20-step dependency chains where parallelization is possible (Search extraction should not wait for Pricing characterization).
Adopted: Step 4 (Peak Season Protection): Adopted 6-week freeze windows (4 weeks before + 2 weeks during peaks); 'soak before freeze' rule (no production changes < 4 weeks before freeze) is essential and Proposal 1 articulates it clearly.
Adopted: Step 5 (Pricing Module Characterization): Adopted explicit black-box golden-master baseline from characterization test suite covering all 8 countries, 3 currencies, 4 languages, all promotion types. The framing 'characterization tests become the golden master' is precise and operationalizable.
Adopted: Step 6 (Test Coverage Improvement): Adopted targeted coverage goal (70%+ for extract-candidate modules, 80% for new service code) and gates blocking extraction below 60%. The insight that mutation testing verifies test quality (not just line coverage) is valuable.
Adopted: Step 11 (Saga Pattern Framework): Adopted explicit compensating-transaction framework and idempotency-key handling end-to-end. The distinction between choreography and orchestration is valuable framing for checkout complexity.
Adopted: Step 18 (Load Testing and Peak Capacity Validation): Adopted multi-stage load testing (base → ramp → sustain → spike → degrade) with realistic user-behavior simulation and per-service bottleneck analysis. The failure-mode analysis (top 10 risks) is a useful template.
Rejected: 24-Step Serialization (actuallt 20 steps): Proposal 1's dependency chain creates artificial critical-path length. For example, Step 8 (Test Coverage Improvement) depends on Step 3 (Domain Analysis), but test coverage for Search can begin in parallel with Pricing characterization; they are independent. My proposal parallelizes Pricing characterization (S5) as month-1 work independent of data platform (S7).
Rejected: Test Coverage to 70%**: Proposal 1 sets target 70%+ coverage for all extracted services. A 2M-line monolith cannot reach this for all modules in 12 months without consuming entire engineering budget. The golden-master characterization at seam level (Proposal 2's insight) is superior and more pragmatic: 100% coverage at the API boundary via replay, 80% for new code in services.
Rejected: Pricing Characterization Step Placement**: Proposal 1 embeds pricing characterization in Step 14 (late in sequence). This creates false dependency: pricing rules can be cataloged in month 1 as parallel work (my S5) independent of deployment platform; there is no reason to wait until Step 14 to start understanding the 200k LOC rules.
Rejected: Phase 2 Refactoring Scope Creep**: Proposal 1 mentions Phase 2 refactoring of pricing rules (DSL, decomposition) within the current 12-month window. This is scope creep into the most complex, least-understood module during a freeze-constrained program. Proposal 2 and my proposal explicitly defer rule decomposition to follow-up program.
Rejected: Monolith Database Decommissioning Sequencing**: Proposal 1's Step 21 (Decommissioning) happens before load testing (Steps 22–24) and team reorganization (Step 19). This removes rollback target while architecture is unproven. Correct order is: load test with rollback available, prove at peak, then decommission only after stability demonstrated.
Note on proposal 3: Proposal 3 distills best insights (golden master, black-box pricing, DDD, CDC, anti-corruption layer) into 12 steps but compresses too much: peak-season protection, dual-write complexity, and team reorganization are underspecified; lacks month-by-month calendar.
Adopted: Step 1 (Team Alignment and Service-First Pods): Adopted the framing of reorganizing teams from business-function (Pricing team, Fulfillment team) to service-aligned (Search Service team, Orders Service team) as foundational change. Proposal 3 articulates this early.
Adopted: Step 2 (DDD and Domain Boundaries): Adopted event-storming workshops and explicit 'Coupling Heatmap' to identify most entangled modules before extraction. This is more rigorous than static code analysis alone.
Adopted: Step 4 (Golden Master Characterization)**: Adopted 'Input Logging' and 'Replay Engine' concept: record production requests, replay against both old and new systems, diff responses. This is simpler and lower-cost than building comprehensive test suites from scratch.
Adopted: Step 7 (Anti-Corruption Layer)**: Adopted framing of CDC + Outbox as 'anti-corruption' boundary: services read events from monolith (CDC), write their own events (Outbox), but never write back to shared monolith schema. This language clarifies the unidirectional dependency.
Adopted: Step 9 (Pricing Black Box)**: Adopted 'Encapsulation without Refactoring' for 200k LOC module: move code as-is, replace dependencies with interfaces (API calls), validate via golden master, defer rule decomposition to follow-up program. This is high-risk-mitigation through conservatism.
Rejected: 10-Step Compression Without Calendar**: Proposal 3 distills into 10 actionable steps but sacrifices critical operational detail. Freeze windows (Dec 1–Jan 15, June 1–July 15) mentioned only in Step 1 ('Freeze Windows' defined but no month-by-month delivery calendar). Proposal 2's explicit calendar is essential for a 12-month migration with two peaks.
Rejected: Dual-Write Complexity Underspecified**: Proposal 3's Step 7 ('Anti-Corruption Layer') mentions outbox pattern but does not detail four-stage cutover playbook (Stage A shadow, Stage B read, Stage C write, Stage D delete). Without explicit stages, teams will invent inconsistent cutover approaches. My proposal (and Proposal 2's) four-stage playbook eliminates ambiguity.
Rejected: Rollback Procedures Not Explicit**: Proposal 3 lacks rollback charter concept (expand/contract migrations, feature flags, rehearsed game days). Step 12 mentions 'chaos engineering' but does not specify when rollback rehearsals happen or how often. Proposal 2's explicit requirement ('every increment ships a feature-flag kill switch and a recorded game-day rehearsal') is operationally clearer.
Rejected: Returns Service Not Explicitly Extracted**: Proposal 3's Step 11 mentions 'Admin Panel' / 'Management Service' vaguely but does not extract Returns as first write-path proof (as Proposal 2 Step 9 does). Returns is the ideal low-stakes service to validate the four-stage playbook before Inventory and Orders. My proposal (S9) makes this explicit.
Rejected: Ordering: Checkout Before Payment**: Proposal 3 Step 10 (Checkout Orchestrator) comes before Step 9 (Payment service). Checkout cannot be decomposed without payment boundary already working; checkout's saga needs to call Payment API. Proposal 2 correctly orders Payment (Step 14) before Checkout (Step 16). My proposal maintains this order (S14 Payment before S16 Checkout).
Rejected: Mobile App Strategy Absent**: Proposal 3 does not address long-lived mobile app sessions, API versioning, or app distribution delays (un-updated app versions). This is material risk for e-commerce but is completely absent in Proposal 3. Proposal 2 (Step 17) and my proposal (S17) address this explicitly.
Note on proposal 1: Proposal 1 articulates pricing characterization and peak-season protection clearly but underestimates how completely data platform work (join elimination, CDC, outbox, four-stage playbook) must precede service extraction.
Adopted: Peak Season Protection Comprehensiveness: Proposal 1's Step 4 is the most complete freeze-window articulation in any proposal: 6-week freeze, 4 weeks before + 2 weeks during, plus rollback runbooks < 30 minutes, incident escalation plan. Adopted wholesale and referenced in my S1.
Adopted: Pricing Characterization as Foundational: Proposal 1 makes explicit that characterization test suite must be built before pricing extraction and becomes CI gate. This is the correct risk mitigation and is adopted in my S5 (separated as parallel, month-1 work).
Adopted: Dual-Write Strategy Detail: Proposal 1's dual-write and 2-week validation post-cutover concept is sound. Adopted in my four-stage cutover playbook (Stage C write cutover, then 2–4 week soak in Stage D before deletion).
Adopted: Load Testing Multi-Scenario Approach: Proposal 1 details chaos testing (kill services, fail databases, degrade gracefully) more explicitly than other proposals. This emphasis on 'no cascading failures' is valuable and I amplify in my S18.
Rejected: Pricing Characterization Placement (Step 14 Late): While Proposal 1 recognizes its importance, embedding it within the pricing-extraction step (S14 in Proposal 1) means cataloging pricing rules is deferred until later in the program. This is inefficient: rule analysis is independent of platform readiness and should start in month 1 (my S5). The false dependency removes parallelization opportunity.
Rejected: Three-Sentencde Test Coverage Requirement Underspecified: Proposal 1's Step 6 says 'target 70%+ coverage for extract candidates' but does not specify how to measure or enforce this across a 2M-line codebase. Golden-master seam-level verification (Proposal 2's approach, adopted in my S6) is more practical: 100% API coverage via replay, 80% line coverage for new code.
Rejected: Service Extraction Sequence Criticality Underappreciated**: Proposal 1's sequence is valid but does not emphasize why Inventory (S9 in Proposal 1, S10 in Proposal 2) must be extracted before Cart (S14 in Proposal 1, S12 in Proposal 2). Cart calls Inventory API to check stock; if Inventory not extracted yet, Cart still calls monolith, creating false progress. Proposal 2's explicit dependency edges (e.g., 'Extract Cart depends on Extract Inventory') are more rigorous.
Note on proposal 2: Proposal 2 is the strongest proposal provided and forms the foundation of my improved plan. Its explicit calendar, scope ladder, four-stage playbook, and table-ownership enforcement set it apart.
Adopted: Every major structural decision from Proposal 2 is adopted: calendar (Dec 1–Jan 15, June 1–July 15 freezes), scope ladder (rungs 1–6 core objective, 7+ optional), four-stage cutover playbook (Shadow-Read, Read, Write, Delete), peak-readiness gate (6 weeks before each peak), seam-level verification (golden master, contracts, shadow diffing, reconciliation), table-ownership enforcement (ArchUnit, SQL linters), and mid-program re-planning point (month 6).
Adopted: I did not substantially reject any major concept in Proposal 2, only refined by adding: (1) explicit Pricing Rules Catalog (S5) as parallel month-1 work to separate it from data platform readiness dependency, (2) more detail on team restructuring timing (expanded S1), (3) more explicit mobile app versioning strategy (expanded S17), (4) earlier emphasis on chaos engineering (dedicated S18 before peak-readiness gate), and (5) more explicit warehouse-sync improvement procedure with parallel-ingestion validation (S10).
Rejected: No substantial rejections of Proposal 2 approach. The proposal is operationally sound and calendar-aware. Only refinements made where the original was sound but could be more explicit or parallelized differently.
--- PROPOSAL 2 (agent deepseek-flash_refine_2, deepseek/deepseek-flash) ---
Estimated complexity: high
Success metrics: - Independent deployability: at least 4 of the 5 teams release their own artefact without coordinating with another team by month 5, and all 5 by month 9.
- The 30-minute maintenance window is retired by month 6; no release after that date requires a planned outage.
- Deployment lead time from merge to production is 30 minutes or less for a service, and each team releases at least 3 times per week by month 6.
- Zero unplanned downtime attributable to the migration across the 12 months; availability of 99.95% or better inside each peak window.
- Both January and July peaks pass with no migration-caused incident: 12x baseline load sustained, checkout p99 under 5 seconds, error rate under 0.5%, no queue backlog beyond 5 minutes.
- 100% of migration increments that reach production have a rollback demonstrated in a game day and executable in under 30 minutes.
- The rollback controller reverts a canary automatically on error-rate or latency divergence, proven in at least two live rehearsals per open window.
- Hourly reconciliation shows under 0.001% discrepancy on row counts and checksums per module; zero unexplained business-invariant violations; a monetary mismatch triggers automatic rollback.
- Cross-module joins and cross-module writes originating in application code are zero for every module at the moment it is extracted, enforced by database roles and CI rather than by review.
- Stored procedures touching more than one module's tables: zero for every extracted module.
- Pricing parity: 100% agreement with the golden master on a corpus of at least 1,000,000 historical requests across all 8 countries, 3 currencies and 4 languages, both before and after cutover.
- Search freshness improves from a nightly rebuild to under 30 seconds between a product change and its visibility in search results.
- Warehouse inventory freshness improves from 15 minutes to under 2 minutes end to end.
- Customer auth: zero forced logouts during cutover for both storefront and mobile clients, and no version of the mobile app in the field breaks at any point in the program.
- The checkout transaction remains inside the monolith through both peaks; the saga deferral is documented, accepted and signed off before month 12.
- The peak-readiness gate is passed with published evidence six weeks before both peaks, covering 100% of its defined checks.
- Scope ladder rungs 1–8 are complete within 12 months, or the program stops at a rung boundary in a documented, coherent, peak-safe state.
Steps (18):
1. Calendar-first charter, scope ladder and peak-readiness protocol
The binding constraint in this objective is the commercial calendar, not the technology, so the calendar is decided before anything else. Everything later obeys it.
- Declare the hard freezes against the real sales calendar, in the shape 1 December – 15 January and 1 June – 15 July. Inside a freeze only rollback-enabling and hardening changes ship.
- Reserve four 'risky cut' slots per year, roughly March–April and September–October. February, May, August and November are soak and hardening months and carry no new cutover.
- Forbid any cutover step from starting within six weeks of a freeze. Every cutover must end in a freeze-ready state: both paths live, flags reversible, reconciliation green.
- Publish the scope ladder. Rungs 1–8 are the core objective; rungs 9+ are optional. Slippage stops at a rung boundary in a coherent, peak-safe state, never mid-increment.
- Write the rollback charter: expand/contract schema change, feature-flag kill switch and a game-day rehearsal recorded before go-live.
- Write the abort criteria: the conditions under which the program stops, and who signs off.
- Create a migration enablement squad of six engineers on rotation from the five teams. It owns the platform, the shared cuts and the risky shared data work.
- Budget 40–50% of the five teams' capacity for migration and staff the ladder to that budget rather than filling the year.
2. Executable architecture map, table ownership and boundary enforcement (depends on: 1)
Five teams committing to one repository will silently re-couple anything that is separated and not policed, so enforcement is part of the map, not a later step.
- Run distributed tracing on the monolith for four weeks before drawing any boundary. Real call paths beat static imports for finding true coupling.
- Build a table-to-module and query-to-module map by parsing every SQL statement, ORM mapping and stored procedure, cross-checked against the database's own query logs.
- Assign each of the 350 tables to exactly one owning module. Tables nobody can own are declared contested and scheduled into S7.
- Score each candidate service on coupling, transactional risk, change frequency and peak-path criticality. This ranking drives the extraction order, not intuition.
- Add ArchUnit rules that fail the build on new cross-module Java dependencies, and a SQL linter that fails on cross-module joins and writes. Existing violations are frozen into a baseline file that may only shrink.
- Publish the target service list, the owning team per service and the reasoning as ADRs.
- Re-rank the scope ladder at the month-six review using what the map actually showed.
3. Delivery platform: per-module pipelines, gateway, feature flags, environments (depends on: 1, 2)
No module is extracted until its team can deploy, flag and route on its own.
- Kubernetes namespaces, quotas and autoscaling policies sized for 12x peaks.
- API gateway in front of the monolith from day one as the strangler entry point. Storefront, mobile and back-office traffic all flow through it even while it routes everything to the monolith.
- One CI/CD pipeline and one environment per module. The monolith keeps its pipeline for hotfixes until S5 replaces it.
- A feature-flag service, with every new call path flag-guarded. Flags are the primary rollback instrument for the whole program.
- Golden-path templates for a new service: build, pipeline, observability, health checks, flag integration, database migration tool.
- Two permanent environments: a production-shaped soak environment and a load-test environment able to generate 12x traffic.
- Secrets management and per-environment configuration so behaviour changes never require a monolith redeploy.
4. Observability, business SLOs and the automated rollback controller (depends on: 3)
A canary is only trustworthy if it is judged automatically, so the rollback promise is built once here and reused by every later step.
- Centralised logging, metrics and distributed tracing, with trace correlation across gateway, monolith and every service.
- Instrument the monolith's blind spots: query latency by module, connection-pool saturation, Lucene rebuild duration, warehouse file-exchange lag.
- Define SLOs on business outcomes: checkout success rate, order confirmation p99, search latency, payment authorisation rate, price computation latency, warehouse sync freshness.
- Attach an error budget to each SLO. When a service burns budget, its rollout stops and its flags revert automatically. No negotiation during a peak.
- Build the rollback controller: on error-rate or latency divergence during a canary, the gateway shifts traffic back and disables flags without human action.
- Per-service dashboards a tired engineer can read at 03:00, plus one program dashboard showing progress against the scope ladder.
5. Split the deployment unit and retire the 30-minute maintenance window (depends on: 2, 3)
This is the cheapest large win in the program and it delivers the headline objective — independent deployability — before any process separation, by splitting the build and the release train while the code still runs together.
- Split the single artefact into one build per owning module with a shared parent.
- Allow modules to be released as separate artefacts on the existing runtime first. Independent deployability is a build and release property long before it is a topology property.
- Retire the two-week coordinated release train. Each team gets its own pipeline, cadence and on-call rota, with the gateway and schema compatibility as the contract between teams.
- Adopt expand/contract database migrations so schema and code changes no longer have to ship together.
- Replace the maintenance window with blue-green deployment on two identical stacks, traffic switched at the gateway and rollback performed by switching back.
- Publish the measurement: deployment lead time, deployment frequency per team, and the share of releases that needed no coordination with another team.
6. Seam-level verification: golden master, contracts, shadow diffing and reconciliation (depends on: 2, 3)
A two-million-line monolith cannot reach blanket coverage in a year. Verification is aimed exactly where the cut will be made, which is where it is affordable and where it actually pays.
- Build a characterization harness that records real production requests and responses, anonymised, as a golden master. This is the safety net for every extraction.
- Require every extracted service to pass the golden master on its public API before it takes live traffic, producing a diff report rather than a pass/fail.
- Consumer-driven contract tests between the monolith and each new service, and between services, so a breaking change breaks a build rather than production.
- Shadow traffic mirroring live requests to the new service with field-by-field comparison. The traffic ramp is gated on the divergence rate.
- Per-module data reconciliation as a first-class test: row counts, checksums and business invariants on a schedule, with an owner and an alert threshold.
- Synthetic canary transactions that run a real checkout, return and search every few minutes and alert on functional regression before customers notice.
- Track line coverage only for newly written service code, where the target is 80%. Blanket coverage of the monolith is explicitly not a goal.
7. Data platform: schema ownership, join elimination, CDC, outbox and the four-stage cutover playbook (depends on: 2, 3, 6)
The hardest part of the program, and the part that does not depend on service extraction, so it starts in month one and runs in parallel with everything else.
- Enforce ownership inside the database: one PostgreSQL role per module, able to write only its own schema and read others only through defined views. Cross-schema writes are rejected by the database, not by convention.
- Inventory every stored procedure, attribute it to one module, and either move it into that module's code or leave it as a module-private function. After a module is extracted, no stored procedure may touch two modules' tables.
- Eliminate cross-module joins one at a time, replacing each with an API call, an event-fed read model or a duplicated read-only projection. Track the count per module and drive it to zero before that module is cut.
- Stand up change data capture with Debezium reading the PostgreSQL WAL into Kafka. This publishes monolith domain events with no application change, the lowest-risk start available.
- Add a transactional outbox for new services so their events and their state changes commit together.
- Adopt one reusable four-stage cutover playbook and apply it identically every time. Stage A: the service owns its schema logically, reads from CDC into its own store and serves shadow traffic only. Stage B: reads cut over, the monolith stays system of record. Stage C: writes cut over and the monolith's tables become read-only replicas fed by reverse CDC. Stage D: old tables and dead code are dropped only after a full peak or four clean weeks, whichever is longer.
- Make stage C genuinely reversible: because the sync direction can be flipped, rolling back a write cutover is a configuration change plus a reconciliation pass, not a data restore.
- Build the reconciliation service once, here, so every later cutover has an objective consistency check with thresholds and owners.
- Deliberately defer the 1.2 TB physical split. Services start on the existing cluster in their own schemas; physical separation is post-program work.
8. Rung 1 — Extract Catalogue and Search (depends on: 5, 6, 7)
The first extraction: read-heavy, mostly isolated, no transactional risk. It also pays for itself, because replacing the nightly Lucene rebuild with real-time indexing is a visible business win that buys political cover for the harder cuts.
- Create a Catalog service owning product, category and media tables plus its own search index.
- Feed it from CDC so product and price changes appear in search within seconds instead of after a nightly rebuild.
- Route through the gateway behind a flag and ramp 1% → 5% → 25% → 50% → 100%, with the rollback controller able to revert to the monolith's internal Lucene path at any point.
- Run shadow traffic and compare result sets before any live traffic, then keep the old index warm for two weeks after full cutover.
- Include the mobile app in the same ramp, since it hits the same endpoints.
- Land this cut in a risky-cut slot and let it soak at least four weeks before the freeze.
9. Rung 2 — Extract Returns, the first write path (depends on: 5, 6, 7)
Second extraction and the first that owns writes and a database. Returns is chosen because it is off the peak-critical path, has modest coupling, and exercises the full four-stage playbook at low stakes.
- Build the Returns service with its own schema, consuming order and customer events rather than joining their tables.
- Run the playbook end to end: shadow reads, read cutover, then write cutover with reverse CDC keeping the monolith's tables current.
- Prove the rollback path in a game day before write cutover, including a reconciliation pass and a re-run of the golden master.
- Keep the back-office returns screens on the monolith for now, so staff workflow is untouched by this step.
- Record every friction point and correct the playbook. The real output of this step is a proven, reusable procedure, not just one service.
10. Rung 3 — Extract Inventory and retire the 15-minute warehouse file exchange (depends on: 5, 6, 7)
Removes one of the sharpest coupling points in the system and unblocks the checkout work. Inventory couples the monolith to an external warehouse process rather than to other modules, so it can run in parallel with the other early cuts.
- Build the Inventory service to ingest the warehouse feed directly and publish stock-level events.
- Preserve the existing file-based interface for the first weeks, running the new ingest in parallel with the legacy feed and reconciling hourly until they agree.
- Keep the monolith's inventory tables as an event-fed projection, so cart and checkout keep working unchanged during the cut.
- Design reservation semantics now — reserve, confirm, release, with expiry — even though checkout is not yet extracted. The API is needed later and is cheap to get right here.
- Load-test inventory ingest at 12x, because the warehouse feed schedule and the sales peaks do not always coincide.
- Cut over reads first, then writes, with the rollback controller able to restore the file feed as the source of truth.
11. Rung 4 — Extract Customer Accounts and Loyalty with a conservative auth strategy (depends on: 5, 6, 7, 9)
Customer accounts and loyalty, including the authentication decision. Auth is the step that most often derails e-commerce migrations, so the auth path is deliberately moved last and guarded hardest.
- Build the Customer service owning profile, address and loyalty tables, with country-specific loyalty rules expressed as data where possible and as code where not.
- Keep authentication in the monolith for the first phase. Move token issuance only once customer data is stable, and never within four weeks of a freeze.
- Introduce distributed session handling and a token-validation API so services can verify identity without querying the monolith database.
- Cut over reads, then writes, with reverse CDC, validating against the golden master across all 8 countries and 4 languages.
- Verify the mobile app's session behaviour explicitly, since it holds long-lived sessions the storefront does not.
- Move loyalty point accrual and redemption last, because a loyalty error is a customer-visible financial error, not a technical incident.
12. Rung 5 — Extract Cart (depends on: 8, 10, 11)
The cart is stateful and sits directly in front of checkout. It is done before pricing because the checkout path needs a stable cart boundary to call.
- Build the Cart service on Redis for session and line-item state, validating products and inventory through service calls rather than database joins.
- Make every cart operation idempotent, because a retried add or remove during a peak must not duplicate a line item.
- Keep the cart tables in the monolith as a read-only projection fed by events, for rollback and for the not-yet-migrated back-office screens.
- Ramp traffic while monitoring cart abandonment rate as the business metric, since cart latency shows up as lost revenue rather than as errors.
- Exercise anonymous and authenticated carts separately; they follow different paths and fail in different ways.
- Land this cut in a risky-cut slot with a full four-week soak before the freeze.
13. Rung 6 — Extract Pricing and Promotions as an unchanged black box (depends on: 5, 6, 7)
Extracts the 200,000-line pricing module without rewriting it. The rules are not understood by anyone, so they are wrapped and characterized rather than reverse-engineered. Rule decomposition, documentation and a DSL are explicitly out of scope for these twelve months.
- Build a golden master corpus from at least a million real historical pricing requests and their recorded outputs, covering all 8 countries, 3 currencies, 4 languages, plus every promotion type that can be discovered.
- Invert the module's dependencies rather than its logic: pricing obtains customer, product and inventory data from event-fed read models it owns, not from synchronous fan-out to three services. A fan-out on the price path is the wrong shape at 12x peak.
- Move the pricing code into its own service unchanged, owning its tables after cutover, and expose a single decision API.
- Run it in shadow mode for at least four weeks against live traffic, comparing every computed price with the monolith. Any divergence blocks the ramp.
- Cut over behind a flag with per-country ramps, since a pricing error is a financial and legal exposure in each jurisdiction rather than a technical incident.
- Keep the in-monolith evaluator available and warm as the rollback path for at least one full peak after cutover.
- State in writing that rule decomposition is deferred to a follow-up program, so it does not creep back into this one.
14. Rung 7 — Extract Payment under a stricter regime than anything else (depends on: 5, 6, 7)
Payment mistakes are irreversible and regulatory, so this module gets the strictest controls in the program.
- Build the Payment service owning the integration with the three providers: tokenisation, authorisation, capture, refund and provider webhooks.
- Reduce PCI scope rather than expand it. No raw card data at rest in the new service, credentials in secrets management, no card data in logs or traces.
- Make every payment operation idempotent with explicit idempotency keys, because retries at peak are normal and double charges are not recoverable.
- Cut over provider by provider rather than all three at once, starting with the lowest-volume provider.
- Run the golden master across all decline, timeout, partial-authorisation and refund scenarios, and rehearse the fallback to the monolith's direct provider integration.
- Verify fraud detection and 3-D Secure paths explicitly, since they are usually the least covered and the most visible when they break.
- Land this cut early in a risky-cut slot so it soaks well before the freeze.
15. Rung 8 — Extract Order Management with an explicit state machine (depends on: 9, 10, 13, 14)
Order management becomes the record of truth for the order lifecycle, after the services it depends on exist and are stable.
- Build the Order service with its own database and an explicit order state machine that validates every transition.
- Introduce event sourcing for order status so the audit trail satisfies regulators and fulfilment teams, and so state can be rebuilt after an incident.
- Consume events from payment, inventory and returns rather than polling or joining.
- Cut over reads first for the five teams that query orders, then writes, keeping the monolith's order tables as a reverse-CDC projection.
- Reconcile order counts and monetary totals hourly against the monolith throughout the transition. A monetary mismatch is an immediate rollback, not a ticket.
- Load-test concurrent order state transitions at peak, since the state machine becomes the new serialisation point.
16. Keep the checkout transaction in the monolith for the first peak, and decide on the saga afterwards (depends on: 12, 13, 14, 15)
This is the deliberate difference from the obvious plan. Checkout is the single highest-risk cut and it sits directly on the peak-critical path. A distributed saga across pricing, inventory, payment and orders buys elegance at the cost of the two things the brief protects most: January and July sales.
- Thin the monolith's checkout into a synchronous orchestrator that calls the Pricing, Inventory, Payment and Order services through the gateway.
- Implement compensation inline in the orchestrator — a failed authorisation releases the reservation, a failed order creation voids the authorisation — without introducing a general saga framework.
- Propagate idempotency keys end to end so a retried checkout cannot double-charge or double-reserve.
- Handle the peak case explicitly: when inventory or pricing is slow, checkout must fail to a retryable state, never to a half-committed order.
- Require the peak-readiness gate before the cut that makes checkout depend on remote calls. A failed gate is a stop, not a delay; the monolith stays authoritative.
- Review after a full peak whether the orchestrator is worth extracting as a saga-based Checkout service. That decision belongs to the follow-up program, with peak data in hand.
- Document and sign off the deferral, so it is an accepted design choice rather than an unfinished step.
17. Migrate the back-office, storefront and mobile clients off the monolith database (depends on: 16)
Until the clients move, the monolith's database stays a dependency even where the logic has already left.
- Refactor back-office screens to consume service APIs through the gateway, replacing direct SQL access table by table, starting with orders and customers.
- Add aggregation endpoints where a screen needs several services, plus a short-lived cache so 300 staff do not multiply load on the new services.
- Update the server-rendered storefront to call service APIs while keeping the existing rendering path working behind a flag, so a rendering regression is a flag flip rather than a rollback.
- Point the mobile app at the gateway for migrated endpoints and keep the old endpoints alive for un-updated app versions. No version of the app in the field may break at any point in the program.
- Publish API versioning rules and deprecation windows so teams can change their services without coordinating with client releases.
- Load-test the back-office with 300 concurrent staff on top of peak storefront traffic, since the two now share services.
18. Decommission the extracted modules, validate the second peak, write the exit report (depends on: 17)
Removes what is left and proves the new architecture survives a peak. This step is as much about proving the state is coherent as about deleting code.
- Delete dead code and dropped tables module by module, only after a module has run a full peak or four clean weeks, whichever is longer.
- Keep read-only access to the old database for a defined period for historical and regulatory queries, then archive and decommission it.
- Replace the monolith's remaining cross-module reads with service calls or event-fed projections. The monolith should now be a small set of modules plus the checkout orchestrator.
- Re-run the full 12x load test against the new topology across all 8 countries, 3 currencies and 4 languages, and tune autoscaling, connection pools and broker partitions from the results.
- Run chaos game days: kill each service in turn and confirm the storefront degrades gracefully rather than failing completely.
- Confirm and publish the peak-readiness gate evidence before the second peak. A failed gate defers remaining work rather than risking the peak.
- Write the exit report: final service boundaries, data ownership, runbooks, SLO history, the scope-ladder rung actually reached, and the list of work explicitly deferred to a follow-up program.
Note on proposal 1: Technically rich and well sequenced, but it spends the engineering budget on an unachievable coverage target and treats rollback of data as a consequence rather than the central design constraint.
Adopted: The peak-season freeze framework with explicit rollback runbooks (Step 4) — a 6-week freeze with rehearsed rollback is the right shape and I keep it.
Adopted: Shadow traffic with response comparison before ramping live traffic (Step 8/9) — it is cheap, objective evidence and it gates every ramp in my plan.
Adopted: Extract pricing as-is first and refactor later (Step 15 phase 1) — the instinct not to rewrite rules nobody understands is correct.
Adopted: Keeping read-only access to the old database after cutover (Step 21) — cheap insurance, and I extend it to a full peak rather than two weeks.
Rejected: Step 6's goal of raising monolith coverage from 25% to 70% across Search, Inventory, Customer, Cart and Payments — a 2-million-line monolith will not reach that in twelve months, and the same effort spent on golden-master and contract verification at the extraction seam buys far more safety.
Rejected: Step 11, building a saga orchestration framework before payment extraction (Step 12) — it introduces a distributed transaction on the checkout path a full window before payment has been independently proven, so I extract payment first and defer the saga entirely.
Rejected: Step 20, decommissioning the monolith and dropping tables before the second-peak load test (which runs at Step 22) — that removes the rollback target while the new topology is still unproven.
Note on proposal 3: The sharpest of the three on pricing and on data movement, but it compresses a 12-month two-peak program into 12 steps and never reconciles its sequencing with the calendar.
Adopted: The golden-master replay engine comparing old and new responses (Step 4) — this is the single most valuable testing idea in the round and it is the safety net for every cut in my plan.
Adopted: Per-country ramps for the pricing cutover (Step 9) — a pricing error is a legal exposure per jurisdiction, so country-by-country ramping is right.
Adopted: Replacing the nightly Lucene rebuild with real-time indexing (Step 5) — this reframes an extraction as a business win and buys political cover for the risky cuts.
Adopted: The 'Checkout Orchestrator' with compensation (Step 10) — adopted but moved out of this 12-month window and placed behind the peak gate.
Rejected: There is no month-by-month calendar and peak-season protection is compressed into a single final step (Step 12) — the brief's hardest constraint is January and July sales, and this plan schedules Pricing (S9) and Checkout (S10) with no freeze protection around them.
Rejected: Step 7's instruction that new services read from read-only replicas of the legacy database — that keeps every service coupled to the monolith's schema and defeats the point of transferring ownership, so I replace it with CDC-fed per-service stores.
Rejected: Step 11's 'Final Monolith Decomposition' drops extracted tables and deletes monolith code before any peak has run against the new topology — I hold each drop until the module has survived a full peak or four clean weeks.
--- PROPOSAL 3 (agent qwen3.8-flash_refine_3, alibaba/qwen3.8-flash) ---
Estimated complexity: high
Success metrics: 1. Zero unplanned downtime during the 12-month migration and subsequent peaks.
2. Peak season (Jan/Jul) capacity maintained at 12x baseline with no performance degradation in checkout flows.
3. 100% of Pricing and Promotion transactions match the Golden Master characterization tests post-extraction.
4. Five teams deploying independently at least once per week without coordination conflicts.
5. All monolith-to-service data synchronization latency under 2 seconds (near real-time).
6. Database size reduced by >40% through extraction and cleanup of legacy unused tables.
7. Search index refresh time reduced from 24 hours (nightly) to < 1 minute (real-time).
Steps (16):
1. Program Governance, Peak Calendar, and Scope Ladder
Establish the binding constraints of the program before any technical work begins. The calendar dictates that the January and July sales peaks are immovable objects; therefore, all migration steps must be scheduled around them.
2. Platform Foundation: Kubernetes, Gateway, and Observability (depends on: 1)
Deploy the infrastructure layer required to run services independently and observe traffic flow. This includes a Kubernetes cluster for workloads, an API Gateway as the central routing control point, and a full observability stack (Tracing, Metrics, Logs). The Gateway is the primary mechanism for rollback via traffic shifting.
3. Data Foundation: CDC, Outbox Pattern, and Transactional Events (depends on: 1, 2)
Implement Change Data Capture (Debezium) and a Transactional Outbox pattern in the monolith. This creates the event backbone required for eventual consistency and allows new services to subscribe to monolith changes without touching the legacy code logic. This step runs in parallel with platform setup.
4. Architectural Decoupling: Table Ownership and Anti-Corruption Layer (depends on: 2)
Define strict ownership for the 350 tables and implement an Anti-Corruption Layer (ACL) to intercept cross-module dependencies. This involves creating separate database schemas or logical boundaries for high-coupling areas like Orders and Catalogue to prepare for physical separation.
5. Characterization Test Harness: The Golden Master (depends on: 2, 3)
Build a replay engine and capture a 'Golden Master' corpus of production traffic. This automated test suite records request/response pairs from the monolith, creating a baseline for validation. This is critical for the Pricing module and high-traffic endpoints where refactoring is impossible.
6. First Extraction Pilot: Catalogue and Search (Read-Heavy) (depends on: 3, 4, 5)
Extract the Catalogue and Search services. These are low-risk (read-heavy) and validate the strangler fig pattern. Implement real-time search indexing via CDC events, replacing the nightly Lucene rebuild. Use the Golden Master to verify product data and search results match the monolith.
7. Second Extraction: Inventory Synchronization (depends on: 3, 5)
Extract Inventory management, specifically handling the integration with the external warehouse system (15-minute sync). This removes a critical dependency from the monolith and enables real-time stock visibility. The service acts as the single source of truth for stock levels.
8. Third Extraction: Customer Profile and Identity (depends on: 3, 4)
Extract Customer Accounts and Profile management. Move authentication logic and customer data ownership to a dedicated service. Ensure the Mobile App and Storefront can authenticate against the new service while maintaining session compatibility via JWT or shared session state.
9. Pricing Module Stabilization: Black Box Extraction (depends on: 5)
Extract the 200,000 LOC Pricing and Promotions module as a 'Black Box' service. Do not refactor the logic; wrap it. Use the Golden Master to validate 100% accuracy across all 8 countries and complex promotion rules. This step is strictly scheduled outside of any peak season.
10. Core Transactional Extraction: Orders and Order Management (depends on: 6, 7, 8, 9)
Extract the Order Management domain, including order creation, state machines, and lifecycle tracking. This service acts as the consumer of events from Inventory, Pricing, and Customer services. It replaces the monolith's direct order processing logic.
11. Checkout Orchestration and Saga Implementation (depends on: 7, 9, 10)
Implement the Checkout Service, acting as the orchestrator (Saga) for the payment process. It coordinates the distributed transaction across Cart, Pricing, Inventory, and Payments. It handles compensating transactions (e.g., releasing inventory on payment failure) to ensure data consistency.
12. Payment Provider Integration Service (depends on: 10, 11)
Extract the logic responsible for connecting to the three payment providers. This service handles authorization, capture, and refunds. By isolating this, the monolith no longer holds sensitive payment processing logic, reducing PCI scope and coupling.
13. Return and Refund Workflow Extraction (depends on: 10, 12)
Extract the Returns and Refunds logic. This service consumes order events to trigger return workflows, updates inventory, and requests refunds from the Payment Service. This completes the reverse logistics capability as a microservice.
14. Legacy Monolith Decommissioning: Strangler Finish (depends on: 10, 11, 12, 13)
Remove the extracted logic from the monolith. The monolith is now a legacy shell containing only the storefront rendering layer (which delegates to APIs) and potentially the Back-Office (if not yet migrated). This step involves rigorous cleanup of unused code and database tables.
15. Back-Office Migration and Staff Tooling (depends on: 14)
Migrate the Back-Office (300 staff users) to use the new service APIs. This may involve a dedicated BFF (Backend for Frontend) service that aggregates data from Orders, Customers, and Inventory for the staff UI, replacing direct database joins in the monolith.
16. Operational Handover and Autonomous Team Setup (depends on: 15)
Finalize team ownership. Each of the five teams is assigned to specific services (e.g., Team A owns Inventory and Search, Team B owns Orders and Checkout). Transfer on-call rotations and disaster recovery runbooks to the new services.
Note on proposal 1: Excellent on technical detail and test coverage, but too linear and ignores the 'Deployment Unit' split as a prerequisite for independent team velocity.
Adopted: Adopted the 'Black Box' strategy for Pricing (S5/S9) to mitigate risk of complex rule logic.
Adopted: Adopted the strict 'Peak Season Protection' calendar (S1) to ensure no risky changes happen during Jan/Jul.
Adopted: Adopted the 'CDC and Event Driven' infrastructure (S3) as the foundation for data synchronization.
Rejected: Rejected 'Step 8: Test Coverage 70%' as a hard metric for the whole monolith; it is unrealistic for 2M lines in 12 months. Adopted 'Golden Master/Characterization' for critical paths instead.
Rejected: Rejected extracting 'Orders' (S10) before 'Inventory' and 'Pricing'; the saga requires the components to exist.
Note on proposal 2: The most strategically sound regarding data and testing rigor, correctly identifying 'Golden Master' and 'Table Ownership' as key enablers.
Adopted: Adopted 'Step 6: Seam-level Verification' (S5 in my plan) using Golden Master/Shadow traffic for validation.
Adopted: Adopted 'Step 7: Data Platform' strategy, enforcing table ownership and CDC.
Adopted: Adopted the 'S1: Program Setup' governance model which prioritizes the freeze windows.
Adopted: Adopted the 'S5: Split Deployment Unit' concept, though I merged the infrastructure aspects into S2/S4 for brevity in this plan.
Rejected: Rejected the sequencing of 'Extract Catalogue (S8)' as the first extraction. While good, 'Inventory (S7)' was moved earlier in my plan because it's a hard dependency for Cart/Checkout and has a specific file-sync bottleneck to fix.
Rejected: Rejected 'Step 16: Compose Checkout' as the very last step; it must happen after all components (Pricing, Inventory, Customers) are stable, which aligns with my S11, but I added S12 for Payments to decouple 3rd party risk.
Note on proposal 3: Good structural approach to the Strangler Fig pattern but underestimates the complexity of the 'Checkout' transactional flow by skipping a dedicated Payment service extraction.
Adopted: Adopted the clear separation of 'Catalogue/Search' (S6) as a low-risk pilot.
Adopted: Adopted the concept of 'Mobilization' (S1) to set the calendar first.
Adopted: Adopted the 'Inventory' extraction (S7) as a key enabler for real-time stock.
Rejected: Rejected the 'Checkout Orchestrator' (S10 in proposal 3) which calls Payment logic directly. It is safer to extract a dedicated 'Payment Service' (S12) to wrap the 3 providers and isolate PCI concerns from the Orchestrator.
Rejected: Rejected leaving 'Inventory and Customer' extraction until step 8/6 of the proposal; they are prerequisites for the Pricing/Order complex interaction.
Your answer has these parts:
- "round_summary": two or three sentences on how the round went as a whole.
- "converging": true if the proposals of this round are more similar to each other than those of the previous round, false otherwise.
- "proposals": one entry per proposal of round 2, each with:
- "proposal": its number,
- "assessment": "improved", "worsened", "mixed" or "unchanged" with respect to its previous version ("no_previous_version" if that agent produced nothing in the previous round),
- "what_changed": a concise account of how it improved or worsened and why (three or four sentences at most),
- "improvements": a list of concrete gains (specific steps, metrics, structure),
- "regressions": a list of concrete losses (dropped steps, vaguer metrics, broken dependencies...),
- "taken": the ideas this proposal visibly adopted from the OTHER proposals of round 1 (not from its own previous version): one entry per idea with "from_proposal" (the number of the proposal it came from), "steps" (the numbers of the steps of that proposal where the idea lives, as listed above; empty if it is not tied to specific steps), "what" (the idea, one sentence) and "why" (how it was used or adapted, one sentence),
- "rejected": the ideas of the OTHER proposals of round 1 that this proposal visibly declined: an explicit contradiction, or a prominent idea it saw and left out while taking the opposite approach. Same fields; "why" gives the evidence (what the proposal does instead). Do not list mere omissions without evidence; an empty list is a valid answer.
[FINAL]
[SYSTEM]
You are an expert reviewer of multi-agent planning processes.
Several LLM agents drafted plans for a task, refined them over a number of rounds while seeing each other's proposals, and finally voted for the best one.
Be exhaustive but precise: name concrete steps, ideas and metrics, never generalities. Judge plans by their fitness for the task as stated, their realism, their completeness, the soundness of their order and dependencies, how measurable their success is and how they handle things going wrong.
You are an impartial evaluator, not a chronicler: assess the proposals and the process on their merits, never rationalise what happened or assume that the outcome was right.
After your analysis, answer in the requested structure.
Every text field you write will be read by a busy person, so write for them: short sentences, one idea each, in short paragraphs. Text fields accept Markdown: separate paragraphs with a blank line, use a bullet list when you enumerate things and plain paragraphs when you explain or argue, and bold at most one key phrase per paragraph. A text of more than three sentences must be split into paragraphs; never deliver a single unbroken block of text.
[HUMAN]
Task given to the agents: "A mid-size European fashion retailer runs its e-commerce on a 10-year-old monolith: Java 8 / Spring, about 2 million lines, one PostgreSQL database of 1.2 TB with 350 tables and heavy use of stored procedures and cross-module joins. It serves 8 countries, 3 currencies and 4 languages, with about 40,000 orders a day and peaks of 12x during sales. The monolith contains: the storefront (server-rendered, plus a separate mobile app hitting the same endpoints), catalogue and search (a Lucene index rebuilt nightly), pricing and promotions (the most complex module, 200,000 lines, with country-specific rules nobody fully understands), cart and checkout with three payment providers, order management, inventory synchronised every 15 minutes with the warehouse system via file exchange, customer accounts and loyalty, returns, and a back-office used by 300 staff. Deployments happen every two weeks as a single artefact with a 30-minute maintenance window; test coverage is 25% and mostly unit tests. Five teams of 8 developers, each organised around a business area but all committing to the same repository.
Plan the migration to independently deployable services over 12 months with no feature freeze, no unplanned downtime and the ability to roll back every step, preserving the peak-season capacity (sales in January and July must not be put at risk)."
THE INITIAL PROPOSALS (round 0):
--- PROPOSAL 1 (agent claudeHaiku4.5_initial_1, anthropic/claude-haiku-4-5) ---
Estimated complexity: high
Success metrics: - All 8 services independently deployed and running in production with zero unplanned downtime during 12-month migration
- Zero data inconsistencies between service-specific databases (validated by monthly reconciliation)
- January and July peak seasons proceed with no degradation: 480k orders/day processed within 5-second checkout SLA
- Test coverage increased from 25% to 70%+ for all extracted services
- Every service deployment is fully automated; manual rollback procedures tested and <30 minutes to execute
- Order processing latency (cart → confirmation) unchanged or improved: maintained under 5 seconds at peak load
- All 5 teams deploying independently: no cross-team deployment coordination required after cutover
- Pricing/promotions service successfully extracted with all 200k LOC of country-specific rules preserved and validated
- Search latency improved or maintained despite architectural change
- Inventory synchronization with warehouse continues reliably: no missed 15-minute sync cycles
- Back-office operations for 300 staff members unaffected by migration; service aggregation endpoints maintain <500ms latency
- Zero payment processing regressions: all three payment providers functioning, fraud detection active, PCI-DSS compliance maintained
Steps (24):
1. Current State Documentation & Target Architecture
Create a detailed map of the monolith to inform service extraction strategy.
- Audit all modules: storefront, catalogue, search, pricing/promotions, cart, checkout, orders, inventory, customers, loyalty, returns, back-office
- Map dependencies between modules, identifying cross-module calls and data flows
- Model future bounded contexts using Domain-Driven Design
- Create technology inventory (libraries, frameworks, protocols)
- Document interface contracts for each module
- Identify which teams own which modules for organizational alignment
2. Data Dependency Analysis & Dual-Write Strategy (depends on: 1)
Untangle the 1.2TB database to support service independence without blocking progress.
- Map all 350 tables to future service domains
- Identify cross-service joins and stored procedures that span domains
- Design per-service database schemas with minimal denormalization
- Create data versioning framework to support rollback
- Plan dual-write patterns: how old monolith and new services will sync during transition
- Document eventual-consistency requirements and conflict resolution
- Design data migration runbooks with clear rollback steps
3. Test Coverage Audit & Improvement Roadmap (depends on: 1)
Build confidence for service extraction by eliminating test blindness.
- Audit current 25% test coverage by module
- Identify coverage gaps in modules scheduled for early extraction
- Establish target of 70%+ coverage for modules being extracted
- Prioritize integration tests over unit tests given monolith complexity
- Create quality gates: no service extraction below 60% module coverage
- Plan for continuous improvement during extraction phases
4. Peak-Season Window Planning & Risk Framework (depends on: 1)
Protect January and July sales by scheduling extractions during safe windows.
- Map annual peak periods: January sales (peak orders), July sales, plus any promotional events
- Define 4-week freeze windows before/during peaks
- Identify lowest-risk windows in each month for major changes
- Create rollback procedures that execute in <30 minutes
- Establish monitoring escalation for changes made near peak season
- Document communication plan with business teams
5. Observability Foundation Setup
Instrument the system for real-time visibility during migration.
- Deploy centralized logging (ELK, Splunk, or similar)
- Set up metrics collection (Prometheus, Datadog, or similar)
- Implement distributed tracing (Jaeger, Zipkin) for request flows across services
- Create dashboards for: requests/sec, error rates, latency percentiles, database load
- Define SLOs: order processing latency p99, checkout success rate, payment authorization speed
- Set up alerts for SLO violations and anomalies
6. Feature Flags, Containerization & API Gateway
Build the technical foundation for canary deployments and controlled traffic routing.
- Implement feature flag system (LaunchDarkly, custom Spring Boot solution, etc.)
- Containerize monolith and all new services (Docker)
- Set up container orchestration (Kubernetes or similar) with service templates
- Deploy API gateway (Kong, AWS ALB) with routing rules
- Implement service-to-service authentication (mTLS, JWT)
- Configure rate limiting and circuit breakers at gateway
7. Deployment Pipeline & Automated Rollback (depends on: 6)
Enable safe, automated deployments with reliable rollback capability.
- Implement CI/CD pipeline with automated testing gates
- Set up blue-green deployment: run old and new versions in parallel, switch traffic atomically
- Build canary deployment capability: route 5%→10%→50%→100% of traffic gradually
- Automate rollback: trigger on error rate threshold, latency spike, or manual command
- Create deployment runbooks for each service
- All deployments must be independent; monolith keeps 2-week cycle until fully extracted
8. Test Coverage Improvement to 70%+ (depends on: 3)
Close test gaps before extracting services to reduce rollback risk.
- Implement integration tests for key flows: order creation, payment processing, inventory updates
- Add contract tests between modules to catch breaking changes
- Use mutation testing to verify test quality
- Target 70%+ coverage for: pricing module, payment module, order management
- Establish automated quality gates: coverage <70% blocks extraction of that service
- Include tests for peak-load scenarios (40k→480k orders)
9. Search/Catalogue Service Extraction & Validation (depends on: 7, 8, 3)
Extract the first service: search is read-heavy, isolated, and low-risk.
- Extract catalogue and search indexing logic from monolith
- Build as independent Spring Boot service with own codebase/deployment
- Create new database schema for catalogue (subset of 350 tables)
- Implement dual-write: monolith writes to both old Lucene index and new service
- Implement canary routing: API gateway sends 10% of search requests to new service, monitor latency and correctness
- Validate results match between old and new service (checksums on result sets)
- Gradually increase traffic: 10%→25%→50%→100%
- Keep dual-write active for 2 weeks post-cutover for rollback safety
10. Event Bus & Service Mesh Infrastructure (depends on: 9)
Build async communication layer required for multi-service coordination.
- Deploy message broker (Kafka recommended for ordering guarantees and peak load of 40k/sec)
- Define domain events: OrderPlaced, PaymentAuthorized, InventoryReserved, etc.
- Implement event schema versioning and compatibility
- Set up service discovery (Consul, Kubernetes DNS)
- Implement distributed configuration management
- Create event publishing library for services to use
- Document saga patterns for multi-step workflows
- Test message broker under peak load (480k messages/day)
11. Inventory Service Extraction & Warehouse Sync (depends on: 10)
Extract inventory as second service: well-bounded, drives warehouse sync complexity.
- Extract inventory logic and reservation system
- Build inventory service with own database schema
- Implement dual-write from monolith to both old and new inventory data
- Preserve existing 15-minute warehouse file exchange, but now via service
- Create inventory events: ReservationCreated, ReleaseRequested
- Implement canary rollout: gradual traffic shift like search service
- Test warehouse sync under peak load
- Validate inventory consistency across monolith and new service before full cutover
12. Customer/Loyalty Service Extraction & Auth Refactoring (depends on: 10)
Extract customer accounts and loyalty: enables independent scaling of auth layer.
- Extract customer account and loyalty program logic
- Build customer service with own database schema
- Separate authentication from monolith: implement API for token validation
- Support multi-tenant loyalty rules (8 countries, country-specific points rules)
- Implement canary rollout with real customer sessions
- Create backwards-compatible customer APIs
- Test account operations at peak concurrency (concurrent logins, loyalty point updates)
- Plan for session management: ensure distributed sessions work across services
13. Saga Pattern Library & Order Orchestration Framework (depends on: 10)
Build the framework for managing distributed transactions across services.
- Implement saga pattern library: choreography-based (event-driven) and orchestration-based patterns
- Support compensating transactions: if payment fails, return inventory reservation
- Handle timeouts and retries with exponential backoff
- Implement idempotency keys to prevent duplicate charges on retries
- Test saga execution under peak load and network failures
- Document patterns for: order placement saga, payment saga, return saga
- Create distributed tracing for saga flows
14. Pricing/Promotions Service Extraction (Phase 1: Extract As-Is) (depends on: 13)
Begin extraction of most complex module (200k LOC) without initial refactoring.
- Extract pricing engine as-is with minimal refactoring to reduce initial risk
- Preserve all country-specific rules and business logic
- Build service boundary: accept pricing requests, return prices/promotions
- Create feature tests that document all 200k LOC behavior
- Map all promotion types to test scenarios
- Test with real country/currency/language combinations
- Implement as service behind same interface initially
- Prepare for Phase 2 refactoring once stable in production
15. Pricing/Promotions Service Refinement (Phase 2: Rules Refactoring) (depends on: 14)
Gradually improve pricing service maintainability without breaking production.
- Document the 200k LOC of complex rules in machine-readable format
- Refactor rules engine into composable components
- Build DSL for country-specific promotion rules
- Decompose monolithic rule evaluation into smaller decision trees
- Use feature flags to A/B test refactored rules vs old implementation
- Optimize performance: reduce calculation time for promotions at checkout
- Validate that refactored logic matches original behavior across all countries
16. Payment Service Extraction & Security Hardening (depends on: 13)
Extract payment processing with extreme rigor given PCI/regulatory requirements.
- Separate payment logic from checkout: payment validation, three-provider integration
- Build payment service with encrypted credential storage, no raw card data in logs
- Implement fraud detection integration and decline handling
- Audit for PCI-DSS compliance: minimal data exposure, encrypted transport
- Implement E2E testing for all three payment provider scenarios
- Load test payment service: 500+ payments/sec at peak
- Implement idempotent payment requests: prevent double-charging on failures
- Create detailed rollback procedures: how to fall back to direct monolith payment handling
17. Order Service Extraction & Event Stream (depends on: 13, 16)
Extract order management: central service coordinating multiple workflows.
- Extract order creation, status tracking, and management logic
- Build order service with event stream: OrderCreated, PaymentAuthorized, InventoryReserved, OrderConfirmed
- Support order querying by all 5 teams (inventory, fulfillment, customer service, etc.)
- Implement order event sourcing for audit trail and replay capability
- Create order state machine: validate state transitions
- Test concurrent order processing at peak load (40k orders/day)
18. Checkout Service Composition via Saga (depends on: 17)
Compose checkout from independent payment, inventory, and order services using sagas.
- Build checkout service that orchestrates: cart validation → pricing calculation → inventory reservation → payment authorization → order creation
- Use saga pattern: if payment fails, release inventory reservation automatically
- Implement distributed transaction semantics: all-or-nothing guarantee
- Support three payment providers transparently
- Test all failure scenarios: payment declines, inventory unavailable, warehouse system down
- Implement timeout handling: what happens if inventory service is slow at peak
- Validate checkout latency remains <5 seconds at peak load
19. Back-Office Integration with Service APIs (depends on: 18)
Update back-office (used by 300 staff) to coordinate across all services.
- Create service aggregation endpoints: orders endpoint calls order service + payment service + inventory service
- Update back-office UI to call new service APIs instead of monolith
- Implement service discovery: handle service availability transparently
- Create caching layer: reduce latency for frequently accessed data
- Test with 300 concurrent staff users
- Implement search across all orders/customers via service APIs
- Add retry logic and timeouts to handle service failures gracefully
20. Storefront & Mobile App Refactoring (depends on: 19)
Update client applications to use new service architecture transparently.
- Update server-rendered storefront templates to call service APIs
- Update mobile app endpoints (already separate, now points to services via gateway)
- Implement client-side caching: reduce latency impact of distributed calls
- Maintain backwards compatibility: old clients must still work
- Update API versioning: enable service changes without breaking clients
- Implement request tracing: correlate user requests across services
- Test storefront and mobile under peak load scenario (480k orders/day)
21. Legacy Database Deprecation & Data Migration (depends on: 20)
Safely decommission the monolith database once all services are independent.
- Verify all data has been migrated to service-specific databases
- Maintain 2-week read-only access to old database for emergency queries
- Archive old database snapshots (regulatory requirement for order history)
- Update backup/recovery procedures: now per-service instead of monolith
- Verify no remaining cross-service joins depend on monolith schema
- Document data mapping for future reference
- Decommission old database infrastructure
22. Load Testing & Performance Optimization (depends on: 21)
Validate new architecture meets production capacity requirements.
- Simulate peak load scenario: 480k orders/day (40k baseline × 12)
- Test across 8 countries, 3 currencies, 4 languages simultaneously
- Identify bottlenecks: service latency, database query performance, message broker throughput
- Optimize hot paths: pricing calculations, search queries, payment processing
- Test cache effectiveness: Lucene search response times, pricing cache hit rates
- Validate database connection pools don't exhaust under peak load
- Create load testing environment: realistic data, all 5 teams' concurrent usage
23. Documentation & Knowledge Transfer (depends on: 22)
Codify migration experience and new architecture for long-term success.
- Document final service boundaries: APIs, responsibilities, data ownership
- Create operational runbooks: how to deploy each service, how to handle common failures
- Record architecture decision log: why services were split this way
- Document data consistency model: eventual consistency patterns used
- Create troubleshooting guides: common issues and resolutions
- Train each team on their service and API contracts with other services
- Record key decisions and trade-offs (e.g., why search is separate from catalogue, why pricing is monolithic within its service)
24. Production Stabilization & 30-Day Monitoring (depends on: 23)
Establish stable operation and prove architecture meets requirements.
- Run 30-day monitoring period observing: error rates, latency, resource utilization
- Establish performance baselines: P99 latency per service, throughput, error rates
- Document SLO achievements: order processing speed, payment success rate, search latency
- Create incident playbooks based on observed issues
- Validate peak-load handling (Jan/July sales go normally through new architecture)
- Establish team on-call procedures for service alerts
- Plan for service scaling: autoscaling policies, capacity planning
- Complete full rollback verification: ensure rollback to monolith is always possible
--- PROPOSAL 2 (agent deepseek-flash_initial_2, deepseek/deepseek-flash) ---
Estimated complexity: high
Success metrics: - 100% of planned service extractions completed within 12 months.
- Zero unplanned downtime during January and July peak sales.
- All new services independently deployable with <5 minute lead time.
- 100% of deployments rollback-able within 5 minutes.
- 80% of traffic served by new services by end of 12 months.
- Test coverage increased to 60% for critical modules.
- Deployment frequency increased from bi-weekly to daily.
- Mean time to recovery (MTTR) < 30 minutes.
- Change failure rate < 15%.
- All stored procedures refactored or migrated to services.
- Database decomposed into 5+ independent databases.
- Peak load capacity sustained at 12x with <1% error rate.
Steps (15):
1. Mobilize Program and Define Target Architecture
Launch the migration program and define the target architecture. This step sets the foundation for all subsequent work.
Key activities:
- Establish a steering committee with business, architecture, and operations representatives.
- Conduct domain-driven design workshops to identify bounded contexts and service candidates.
- Define the target architecture: API gateway, service mesh, event-driven integration, and data ownership per service.
- Prioritize service extraction based on business value, risk, and coupling.
- Create architecture decision records (ADRs) and a service roadmap.
Output: a shared vision and prioritized backlog for the migration.
2. Build Platform Foundation for Independent Deployments (depends on: 1)
Build the platform foundation required for independent deployments. This includes infrastructure, tooling, and golden paths.
Key activities:
- Provision a Kubernetes cluster with namespaces for each service.
- Set up CI/CD pipelines per service using GitLab CI or ArgoCD.
- Deploy an API gateway (e.g., Kong) and service mesh (e.g., Istio) for traffic management.
- Implement observability: centralized logging (ELK), metrics (Prometheus/Grafana), and tracing (Jaeger).
- Set up secrets management (Vault) and configuration management.
- Create golden path templates for new services to reduce boilerplate.
Output: a production-ready platform where teams can deploy services independently.
3. Implement Strangler Fig Facade and Monolith Instrumentation (depends on: 2)
Implement the strangler fig facade and instrument the monolith. This allows incremental migration without disrupting users.
Key activities:
- Deploy the API gateway to route requests to the monolith or new services based on path or header.
- Modify the monolith to expose REST APIs for key domains (e.g., catalogue, customer).
- Implement the transactional outbox pattern to publish domain events from the monolith.
- Set up change data capture (CDC) from the monolith PostgreSQL to Kafka using Debezium.
- Introduce feature flags for routing and canary releases.
- Ensure all changes are backward compatible and can be rolled back.
Output: a facade that enables gradual traffic shifting and a data pipeline for synchronization.
4. Establish Continuous Delivery and Test Automation (depends on: 1)
Establish continuous delivery and test automation to support safe, frequent deployments.
Key activities:
- Increase automated test coverage for critical monolith modules (target 60%).
- Implement consumer-driven contract testing (Pact) between monolith and new services.
- Set up automated regression test suites for end-to-end flows.
- Integrate tests into CI/CD pipelines with quality gates.
- Enable blue-green and canary deployments for both monolith and services.
Output: a reliable deployment pipeline that supports rollback and rapid feedback.
5. Extract Catalogue and Search Service (depends on: 3, 4)
Extract the Catalogue and Search service. This is a read-heavy, low-coupling module, making it a good first candidate.
Key activities:
- Create a new Catalogue service with its own datastore (PostgreSQL for product data, Elasticsearch for search).
- Implement data synchronization from the monolith via CDC and events.
- Migrate read APIs for product listing and search to the new service via the gateway.
- Use feature flags to gradually shift traffic, with fallback to the monolith.
- Monitor performance and rollback if issues arise.
Output: an independently deployable Catalogue service serving a portion of traffic.
6. Extract Customer Accounts and Loyalty Service (depends on: 3, 4, 5)
Extract the Customer Accounts and Loyalty service. This service manages profiles, addresses, and loyalty points.
Key activities:
- Create a new Customer service with its own database.
- Synchronize data from the monolith via events (customer created, updated).
- Migrate profile management and loyalty APIs to the new service.
- Keep authentication in the monolith initially to reduce risk.
- Redirect customer API calls to the new service gradually.
Output: an independently deployable Customer service with data ownership.
7. Extract Inventory Service (depends on: 3, 4)
Extract the Inventory service. This service consumes the warehouse file feed directly and maintains real-time inventory.
Key activities:
- Create an Inventory service that reads the warehouse file feed (SFTP) and parses it.
- Publish inventory update events to Kafka.
- Migrate inventory queries from the monolith to the new service.
- Ensure the monolith and other services consume inventory events instead of querying the monolith DB.
Output: an independently deployable Inventory service with real-time updates.
8. Extract Returns Service (depends on: 3, 4, 6)
Extract the Returns service. This module is relatively independent and can be extracted early.
Key activities:
- Create a Returns service with its own database.
- Consume order and customer events to validate returns.
- Migrate returns UI and APIs to the new service.
- Ensure integration with order management for refunds.
Output: an independently deployable Returns service.
9. Peak Season Readiness and Resilience Engineering (depends on: 1)
Prepare for peak seasons and implement resilience engineering. This is critical to avoid downtime during January and July sales.
Key activities:
- Conduct load testing for 12x peak on new services and the monolith.
- Implement circuit breakers, bulkheads, rate limiting, and auto-scaling.
- Define change freeze periods: one month before and during January and July sales.
- Plan migration activities outside freeze windows.
- Run game days for failure scenarios and rollback drills.
Output: a system that can withstand peak loads and a schedule that protects peak seasons.
10. Extract Cart Service (depends on: 3, 4, 7)
Extract the Cart service. The cart is a stateful component that requires careful handling.
Key activities:
- Create a Cart service with its own datastore (e.g., Redis or PostgreSQL) for session and cart items.
- Use the API gateway to route cart operations.
- Synchronize with the monolith via events for product and inventory validation.
- Ensure idempotency and session stickiness.
- Gradually migrate cart traffic using feature flags.
Output: an independently deployable Cart service.
11. Extract Order Management and Checkout Orchestration (depends on: 10, 6, 7, 9)
Extract Order Management and Checkout Orchestration. This is the core transactional flow and requires a saga pattern.
Key activities:
- Create an Order service that orchestrates checkout using the saga pattern.
- Integrate with payment providers, inventory, pricing, and customer services.
- Migrate order placement and management APIs.
- Use events for order status updates.
- Ensure distributed transaction consistency and compensation logic.
Output: an independently deployable Order service handling the checkout flow.
12. Extract Pricing and Promotions Service (depends on: 11)
Extract the Pricing and Promotions service. This is the most complex module with 200k lines of rules.
Key activities:
- Analyze and document the existing pricing rules and country-specific logic.
- Implement a new Pricing service, possibly using a rules engine (e.g., Drools).
- Migrate pricing calculations and promotions to the new service.
- Execute after other services are stable and outside peak seasons.
- Use extensive testing and canary releases.
Output: an independently deployable Pricing service with clear rules.
13. Database Decomposition and Stored Procedure Refactoring (depends on: 3)
Decompose the database and refactor stored procedures. This is a cross-cutting concern that runs alongside service extraction.
Key activities:
- Start with logical separation: create schemas per service and move tables gradually.
- Refactor stored procedures into application code or move them to services.
- Eventually, give each service its own database instance.
- Use CDC and dual-write for data consistency during transition.
- Keep the monolith DB as source of truth until cutover.
Output: a decomposed database with clear data ownership.
14. Reorganize Teams for Independent Deployment (depends on: 1, 2)
Reorganize teams for independent deployment. This step enables long-term autonomy.
Key activities:
- Reorganize teams around services (stream-aligned teams).
- Give each team ownership of its service's repository, CI/CD, and on-call.
- Implement an internal developer platform for self-service deployments.
- Establish service level objectives (SLOs) and error budgets.
Output: autonomous teams that can deploy independently.
15. Post-Migration Optimization and Monolith Decommissioning (depends on: 12)
Optimize after migration and decommission the monolith. This step wraps up the migration.
Key activities:
- After each service extraction, remove dead code from the monolith.
- Gradually reduce the monolith to a smaller core (e.g., back-office).
- Plan eventual decommissioning of monolith components.
- Document learnings and update architecture.
Output: a leaner monolith and a fully service-oriented architecture.
--- PROPOSAL 3 (agent qwen3.8-flash_initial_3, alibaba/qwen3.8-flash) ---
Estimated complexity: high
Success metrics: - **Zero Downtime**: Achieve 100% availability of the e-commerce platform throughout the 12 months, including planned maintenance windows.
- **Deployment Independence**: New services can be deployed independently; no code commit forces a full 30-minute monolith downtime. Time-to-deploy for a new service < 5 minutes.
- **Database Decoupling**: Eliminate cross-service SQL joins. The monolith database write load decreases by 90%.
- **Peak Capacity**: System handles 12x traffic load (approx. 480k orders/day) with < 200ms latency at P95 during load tests.
- **Search Latency**: Product availability reflected in search results within < 30 seconds of inventory update (replacing nightly rebuild).
- **Pricing Stability**: 0% deviation in price calculation results between the new architecture and the legacy 'golden master' characterization tests.
Steps (10):
1. Foundation: Infrastructure, Observability, and Safety Net
Before extracting any service, the team must build the 'operating system' for distributed applications. This step focuses on enabling independent deployment and providing real-time visibility into the legacy monolith. The goal is to create a safety net that makes subsequent refactoring steps low-risk and reversible.
* **CI/CD Pipeline**: Implement a dual-track pipeline. The existing monolith gets a 'speedy' pipeline for hotfixes, while a new pipeline infrastructure is set up (e.g., Kubernetes/ECS) ready for independent service deployment.
* **Observability Suite**: Deploy centralized logging (ELK/Loki), metrics (Prometheus/Grafana), and crucially, **Distributed Tracing** (Jaeger/Zipkin). Even within the monolith, we must map request flows to identify coupling.
* **Service Mesh / API Gateway**: Install an API Gateway (e.g., Kong, Nginx ingress) in front of the monolith. This is the 'strangler fig' entry point. All traffic must flow through here. We will use it to route traffic to new services or fallback to the monolith.
* **Feature Flags**: Integrate a feature management system (e.g., LaunchDarkly, Unleash) to decouple deployment from release. This allows us to deploy code that is inactive and test it behind flags.
2. Domain Analysis and Boundary Definition (Strangler Pattern) (depends on: 1)
You cannot extract a service without knowing the domain. With 2M lines and 'unknown' pricing logic, this step is about mapping the terrain. We aim to identify low-risk, high-cohesion boundaries for the first extractions and mark the 'danger zones' (Pricing) for later.
* **Event Storming**: Run workshops with the five teams to map business flows (e.g., 'Checkout', 'Return') and identify command/event boundaries.
* **Code Hotspot Analysis**: Use static analysis tools (e.g., SonarQube, CodeScene) to find files changed together (logical coupling) and complex methods.
* **Dependency Matrix**: Create a matrix showing which database tables are accessed by which application modules. This is critical for the database refactoring later.
* **Service Extraction Plan**: Finalize the order of extraction. Recommended: **Search/Catalogue** (read-heavy, low transactional consistency risk) or **Inventory** (async, distinct boundary). Avoid 'Pricing' initially due to complexity and 'Checkout' until foundational identity is stable.
3. Data Platform Strategy: Outbox Pattern and CDC (depends on: 2)
The 1.2TB PostgreSQL DB with stored procedures is the 'database of doom' for migration. We must stop using cross-module SQL joins. This step introduces a data change capture layer to allow services to communicate via events rather than DB writes.
* **Database Isolation**: Begin identifying tables exclusive to the chosen first domain (e.g., Catalogue tables). Grant strict read-only access to other modules if possible, or refactor code to remove cross-table joins.
* **Change Data Capture (CDC)**: Deploy a tool (e.g., Debezium or Kafka Connect) to stream PostgreSQL WAL logs to a message broker (Kafka/Pulsar). This creates a stream of data changes that can be consumed by other services.
* **Transaction Outbox**: Refactor the monolith code to use an 'Outbox Pattern' for domain events. Instead of just writing to the DB, it also writes a message to an 'Outbox' table in the same transaction. A relay process moves this to Kafka. This ensures 'at least once' delivery and keeps the monolith's transactional integrity while enabling async communication.
4. Extraction of First Service (The 'Read-Only' Pilot) (depends on: 1, 3)
To learn safely, we extract a 'read-only' service with no transactional complexity. The **Product Catalogue/Search** is the best candidate. It is currently Lucene-based, rebuilt nightly. We will move to real-time indexing to improve product freshness.
* **Build the Catalogue Service**: Create a new microservice that owns the Catalogue database tables. It exposes gRPC/REST endpoints for fetching products.
* **Real-time Sync**: The new service subscribes to the CDC events for product changes (from S3). It updates its internal Lucene/Opensearch index in real-time. This eliminates the nightly rebuild and provides immediate search visibility.
* **Dual Read Path**: The monolith code for 'Search' is modified to check a feature flag. If enabled, it calls the new Catalogue Service; otherwise, it uses the old internal Lucene logic.
* **Shadow Traffic**: Use the API Gateway to duplicate live traffic. Send requests to both the monolith and the new service. Compare the responses. Only when error rates are 0% do we flip the feature flag for production traffic.
5. Extraction of Identity and Customer Accounts (depends on: 4)
Next, we extract the **Customer Account** domain. This serves both the storefront and the mobile app. This is a write-heavy domain, requiring careful transaction handling with the legacy monolith during the transition.
* **Service Implementation**: Implement the 'Customer Service' (JWT generation, profile management, authentication). It owns its own database schema (User, Address).
* **Sync with Legacy**: The service publishes 'UserUpdated' and 'UserCreated' events via Outbox/CDC. The monolith listens to these events to keep its local copy of user data synchronized.
* **Strangler Endpoint**: The API Gateway routes '/api/login', '/api/account' traffic directly to the new service. The monolith stops handling these requests. Front-end applications must be updated to handle the new response format (versioning).
* **Database Decoupling**: Over time, remove read access to the monolith's user table for all other domains, forcing them to use the Identity service.
6. Extraction of Inventory Synchronization (depends on: 5)
Inventory is currently updated every 15 minutes via files. This is a bottleneck. We will extract this into a service that integrates directly with the Warehouse Management System (WMS).
* **Inventory Service**: Build a service that consumes warehouse data feeds (replacing the file drop). It updates a centralized stock level view.
* **Event Publishing**: When stock levels change, publish `StockLevelChanged` events to Kafka.
* **Monolith Integration**: Refactor the Cart/Checkout code in the monolith to listen to these events to maintain a local cached view of inventory or to check stock via an API call rather than a SQL join. This removes the 15-minute latency.
* **Consistency Model**: Since inventory is high-concurrency, design a reservation system (Saga) for this service to prepare for the future extraction of Checkout.
7. The 'Black Box' Strategy for Pricing and Promotions (depends on: 6)
The pricing module (200k lines, unknown rules) cannot be rewritten safely from scratch. We treat it as a 'legacy core'. We will wrap it in a service but keep the internal logic untouched in the monolith initially, or isolate it.
* **Characterization Tests**: Write massive integration tests that record the input/output of the pricing module for all 8 countries and 3 currencies. This creates a 'golden master'.
* **Decouple Dependencies**: Refactor the pricing code to rely only on 'Customer', 'Product', and 'Inventory' data fetched via interfaces, not direct DB calls. This prepares it for extraction.
* **Extract as 'Black Box'**: Wrap the existing pricing logic into a new `Pricing Service`. Move the 200k lines of code into this project. It calls a dedicated read-replica database of the pricing tables. This service does not communicate with others directly but is called by the 'Cart' service.
* **Validation**: Run 'shadow mode' traffic against this new service to ensure it matches the golden master before routing any production traffic.
8. Orchestration Layer: Cart and Checkout (The Saga) (depends on: 7)
Checkout is the highest risk. It requires distributed transaction management. We will implement the Cart as a service and the Checkout process as an orchestrator using Sagas.
* **Cart Service**: Extract cart logic into its own stateless/stateful service (Redis-backed). This decouples the browsing experience from the order processing.
* **Checkout Orchestrator**: Build a new 'Order Service' that does not do the work itself but coordinates the process. When a checkout starts, the Order Service begins a **Saga**.
* **Saga Steps**: 1. Validate Pricing (via Pricing Service), 2. Reserve Inventory (via Inventory Service), 3. Authorize Payment (via Payment Service), 4. Create Order Record. If step 3 fails, step 1/2 must be compensated (rollback).
* **Idempotency**: Ensure all services in the saga accept Idempotency Keys to prevent double-charging or double-stock deduction.
9. Extraction of Payments and Order Management (depends on: 8)
Complete the order lifecycle. Move payment integration and order status tracking out of the monolith.
* **Payment Gateway**: Extract the integration with the 3 providers into a `Payment Service`. This service handles webhooks, refunds, and tokenization (PCI scope reduction).
* **Order Management System (OMS)**: Move the database table `orders` and associated history into a new `Order Service`. It consumes the events generated by the Checkout Saga.
* **Back-office Migration**: The back-office (300 staff) is likely server-rendered. Refactor these screens to consume the new `Order Service` APIs. Remove the back-office's direct SQL access to the orders table. This is crucial for reducing load on the monolith DB.
10. Legacy Cleanup and Peak Season Preparation (depends on: 9)
The monolith should now be a 'hollowed-out' shell (mostly just the legacy pricing rules inside a service or a 'legacy' module). We prepare for the peak sales in Jan/July.
* **Database Downsizing**: Detach the schema ownership. The monolith should ideally only connect to a 'read-only' replica for historical data or a small remnant DB.
* **Performance Tuning**: The new architecture is now the single point of failure. Optimize the message broker (Kafka) and API Gateway for 12x traffic.
* **Chaos Engineering**: Run game-days testing resilience. Kill a service (e.g., Search) and ensure the storefront degrades gracefully (shows empty search results but allows cart access).
* **Final Monolith Decommission**: Identify the remaining monolith code. Delete it. If it's just a 'legacy gateway', replace it with pure API routing. The 'Monolith' label should now refer only to the Pricing Service or similar, not a single deployable unit.
HOW THE ROUNDS WENT (from the round analyses):
Round 0: The agents proposed three migration strategies with distinct strengths. **None fully address the 12-month timeline** given the massive codebase.
* Proposal 1 is the most realistic regarding peak-season risks but delays extraction.
* Proposal 2 establishes a strong platform foundation but fatally delays team reorganization.
* Proposal 3 handles the pricing module pragmatically but lacks granular database details.
Overall, **all plans lack sufficient detail on data migration runbooks** for the database.
Proposal 1: This plan outlines a 24-step process starting with extensive documentation and test coverage improvements before any code extraction. It extracts services incrementally, beginning with read-heavy modules like Search and moving to complex domains like Pricing and Checkout.
The strategy heavily relies on dual-write patterns and strict rollback procedures to protect peak sales seasons. However, **increasing test coverage to 70% before extraction** will likely consume too much of the 12-month timeline.
Proposal 2: This proposal details a 15-step plan that establishes a Kubernetes platform and strangler fig facade before extracting any services. It leverages Change Data Capture and event streaming to decouple the database early in the process.
The plan concludes with team reorganization and monolith decommissioning after extracting core transactional flows. **Delaying team reorganization to step 14** is a critical flaw that will cause organizational friction during the migration.
Proposal 3: This strategy uses a 10-step framework centered on event storming and a robust data platform utilizing the Outbox pattern. It treats the complex Pricing module as a black box wrapped in characterization tests to avoid rewriting unknown rules.
The extraction order prioritizes read-only pilots before moving to stateful domains like Cart and Checkout. While pragmatic, **the 10-step high-level approach** lacks the granular dependency mapping required for a 1.2 TB database.
Round 1: The agents significantly improved their plans by adopting each other's strongest strategic insights. They all converged on a black-box extraction for the pricing module.
They also agreed on using Change Data Capture for database decoupling. The proposals are now much closer in structure, though Proposal 2 stands out for its rigorous handling of constraints.
Proposal 1 (improved): The proposal reduced its step count and significantly improved its sequencing by adopting the black-box pricing strategy. It fixed the overly serialized dependency chain of its previous version by parallelizing read-heavy extractions. However, it still retains a somewhat rigid, linear progression compared to the adaptive approach of Proposal 2.
Proposal 2 (improved): This proposal transformed from a generic template into a highly rigorous, constraint-driven execution plan. It explicitly tackled the hardest constraints by introducing a scope ladder, a rollback charter, and a four-stage cutover playbook. It correctly abandoned the unrealistic goal of blanket test coverage in favor of seam-level verification.
Proposal 3 (improved): The proposal expanded to 12 steps, adding crucial operational layers like strategic freeze planning and core infrastructure setup. It successfully integrated the black-box pricing strategy and CDC patterns, making it much more realistic than its previous version. However, it still lacks the deep data-cutover mechanics and strict calendar enforcement seen in Proposal 2.
Round 2: The agents converged on a **calendar-first approach** with explicit peak-season freezes and seam-level verification. They abandoned unrealistic blanket test coverage goals in favor of golden-master characterization and four-stage cutover playbooks.
Proposal 1 (improved): It abandoned its unrealistic **70% monolith coverage goal**. It adopted the calendar-first, scope-ladder, and four-stage cutover playbook from Proposal 2. It also parallelized the pricing rules cataloging to avoid false dependencies.
Proposal 2 (improved): It refined its strong foundation by explicitly **deferring the checkout saga orchestration** until after the first peak. It also clarified the mobile app versioning and authentication strategies to prevent customer disruption.
Proposal 3 (mixed): It adopted the **golden master and CDC strategies** from the other proposals, improving its data and testing rigor. However, it still lacks the operational depth of the four-stage cutover playbook and explicit rollback rehearsals.
THE PROPOSALS OF THE FINAL ROUND (2), to assess:
--- PROPOSAL 1 (agent claudeHaiku4.5_refine_1, anthropic/claude-haiku-4-5) ---
Estimated complexity: high
Success metrics:
- **Zero unplanned downtime**: 100% availability throughout 12-month migration (excluding planned 30-min blue-green deployments); no production incidents attributable to migration architecture
- **Peak seasons protected**: January and July peaks (480k orders/day) sustain zero degradation caused by migration; checkout p99 ≤ 5 seconds, payment authorization ≤ 2 seconds, error rate ≤ 0.5%, no queue backlog > 5 minutes
- **Independent deployability**: All eight services independently deployable by month 12; each team releases on own cadence (weekly or faster) with zero cross-team deployment coordination; 100% of service releases verified rollback-capable in < 30 minutes
- **Rollback-proven**: Every production increment has rehearsed, documented, tested rollback path (expand/contract migrations, feature flags, reverse CDC); monthly chaos game days validate rollback procedures; zero increments reach production without passing rollback gate
- **Data consistency**: Hourly reconciliation shows < 0.001% row-count and checksum discrepancy between service databases and monolith (pre-decommissioning); zero business-invariant violations (no duplicate orders, no lost payments, no inventory oversells)
- **Pricing correctness**: 100% agreement between new Pricing service and golden-master corpus across 1M+ historical requests covering all 8 countries, 3 currencies, 4 languages, all promotion types; zero pricing errors post-cutover
- **Search freshness**: Product availability reflects in search within < 60 seconds of inventory change (vs. nightly rebuild); search latency p95 unchanged or improved at peak load
- **Warehouse sync improvement**: Inventory synchronization lag reduced from 15 minutes to < 2 minutes end-to-end; 100% of daily warehouse updates processed; no missed sync cycles during migration
- **Payment processing**: Zero regressions with all three payment providers; fraud detection active and effective; PCI-DSS compliance maintained; idempotency prevents duplicate charges; payment success rate ≥ 99.5% at peak
- **Back-office operations unaffected**: All 300 staff seamlessly using service APIs; service aggregation endpoints maintain p95 latency ≤ 500 ms; bulk operations (refunds, order status updates) complete within SLA
- **Test coverage for services**: All newly written service code reaches 80%+ line coverage; golden master validates 100% of public API contracts before production traffic; contract tests (Pact) prevent breaking changes between services
- **Peak-readiness gate passed**: Six weeks before each peak (mid-November, mid-May), gate published showing 12x load test results, capacity headroom, rollback rehearsal duration, and SLO status; failed gate defers work; evidence published publicly
- **Team independence by month 12**: Five teams deployed independently; each owns service codebase, pipeline, database schema, on-call rotation, SLOs; no cross-team pull requests blocking releases; internal developer platform (golden-path templates, self-service deployments) adopted by all teams
- **Scope ladder completed**: Rungs 1–6 reached by month 12 (or deliberately stopped at rung boundary with documented justification); all services proven at peak; monolith reduced to < 5% or decommissioned
- **Calendar adherence**: No major extractions or refactors during freeze windows (Dec 1–Jan 15, June 1–July 15); all production increments land in open windows with minimum 4-week soak before freeze; timeline published and adhered to
- **Event-driven architecture validated**: Kafka message broker handles 480k+ messages/day at peak; no message loss, no ordering violations; outbox pattern ensures every domain event persists atomically
- **Fallback capacity maintained**: Monolith rollback path kept warm and functional (receiving live traffic or ready-to-receive via feature flag) until each service survives one full peak; no service extracted without proven rollback capability
Steps (20):
1. Program Setup, Scope Ladder, Organizational Model, and Peak-Safe Calendar
Establishes the governance framework and constraints that all later work obeys. The calendar is the binding constraint—January and July peaks must not be put at risk—so it is decided first, before any technical choices.
**Inception and Baselines**: Run a two-week inception to establish current state: build time, deployment lead time, change failure rate, MTTR per team, module-change frequency, database load profiles (all measurable, not asserted).
**Calendar and Freeze Windows**: Declare hard freezes from December 1–January 15 and June 1–July 15; only rollback-enabling and hardening changes allowed during freezes. Confirm two open delivery windows per year (February–May and August–November); all migration work must fit these windows. No change on checkout path lands within four weeks of a freeze.
**Scope Ladder**: Define ranked rungs 1–6 that deliver the core objective; rungs 7+ are optional. Slippage means stopping at a rung boundary, never mid-increment. Rungs: 1. Platform ready. 2. Search extracted and proven. 3. Returns and Inventory proven at low stakes. 4. Payment and Orders stable. 5. Checkout orchestration live and soaking. 6. Back-office migrated, monolith core reduced.
**Organizational Model**: Define service-aligned teams (Search, Orders, Inventory, Payments, Customer, Fulfillment) with clear ownership, on-call rotations, and SLOs per service. Each team owns codebase, pipeline, database schema, and incidents by month 6. Transition plan: teams split duties (monolith maintenance + service) until month 3, then shift to service-primary by month 6.
**Rollback Charter**: Every increment ships an expand/contract database change, a feature-flag kill switch, and a recorded game-day rehearsal. No go-live without tested rollback in < 30 minutes.
**Peak-Readiness Gate**: Define gate to run six weeks before each peak (mid-November, mid-May): 12x load test, capacity headroom check, rollback rehearsal, error-budget review. Gate is pass/fail; failed gate defers work to next window.
**Capacity Budget**: Allocate 40–50% of five teams' capacity for migration; staff scope ladder to fit capacity, not to fill the year. Create migration enablement squad of six rotating engineers to own platform, shared cuts, and risky data work.
2. Executable Architecture Map, Table Ownership, and Boundary Enforcement (depends on: 1)
Produces an architecture map that the build itself enforces. Five teams in one repo will silently re-couple anything separated if not policed, so enforcement is embedded in the map.
**Real Coupling via Tracing**: Instrument monolith with distributed tracing; let it run four weeks to capture real call paths—static imports miss true coupling.
**Table Ownership Matrix**: Parse every SQL statement, ORM mapping, and stored procedure; cross-check against database query logs. Build table-to-module and query-to-module map. Assign every 350 table to exactly one owning module; tables nobody can own are 'contested' and scheduled into data work (Step 7).
**Scoring and Extraction Sequence**: Score each candidate service on coupling, transactional risk, change frequency, and peak-path criticality. This ranking (not intuition) drives extraction order.
**Enforcement via Automation**: Add ArchUnit rules to CI to fail builds on new cross-module Java dependencies (existing violations frozen in baseline that may only shrink). Add SQL linter to CI to fail on cross-module joins and cross-module writes (same shrinking baseline). Violations tracked weekly in architecture review.
**Stored Procedure Audit**: Inventory all stored procedures; attribute to owning module; plan move into module code or leave as module-private function. No stored procedure may touch two modules' tables post-extraction.
**Architecture Decision Records**: Publish target service list, owning team per service, and reasoning as ADRs.
**Mid-Program Review**: Hold review at month 6 to re-rank scope ladder using what the map actually revealed. This is the one planned re-planning point of the program.
3. Delivery Platform: Per-Service Pipelines, Gateway, Feature Flags, and Environments (depends on: 1, 2)
Builds the delivery and traffic machinery that makes every later step reversible. No service is extracted until its team can deploy, flag, and route independently.
**Kubernetes and Namespaces**: Extend platform on Kubernetes (or existing container platform) with one namespace per service, quotas, and autoscaling sized for 12x peak (480k orders/day). Establish dev/staging/prod with strict resource isolation.
**API Gateway**: Deploy API gateway (Kong, AWS ALB) in front of monolith as strangler entry point. Storefront, mobile app, and back-office traffic flow through gateway from day one, even while routing everything to monolith. Gateway enforces rate limiting, bulkheads, timeouts, and circuit breakers.
**Feature-Flag Service**: Deploy centralized feature-flag system (LaunchDarkly, Unleash). Require every new call path to be flag-guarded. Flags are the primary rollback instrument; changes to traffic routing require no code deployment.
**Per-Module CI/CD Pipeline**: Give every module its own independent CI/CD pipeline and environment. Monolith keeps current pipeline for hotfixes until Step 5 replaces it. Pipeline includes automated security scanning, performance baselines, and contract-test gates.
**Secrets and Configuration**: Introduce secrets management (Vault) and per-environment configuration. Behavioral changes require no monolith redeploy.
**Golden-Path Templates**: Define reusable templates for new services: build layout, Dockerfile, pipeline stages, observability instrumentation, health checks, feature-flag integration, database migration tool. Extraction starts from template, not blank page.
**Permanent Environments**: Reserve two full-size environments: (1) production-like soak environment for multi-week stability validation, (2) load-test environment capable of 12x traffic generation against production-shaped data (8 countries, 3 currencies, 4 languages, realistic product catalog).
4. Observability, Business SLOs, Error Budgets, and Automated Rollback Controller (depends on: 3)
Makes the system observable so canaries are judged automatically and reverted without human guessing. This is the prerequisite for rollback promises in all later steps.
**Observability Foundation**: Deploy centralized logging (ELK/Loki), metrics (Prometheus/Grafana), and distributed tracing (Jaeger) with trace correlation working across gateway, monolith, and every new service from day one.
**Blind-Spot Instrumentation**: Instrument monolith's unmeasured aspects: query latency by module, connection-pool saturation, Lucene rebuild duration, warehouse file-exchange lag, stored procedure execution time, lock contention.
**Business SLOs**: Define SLOs on business outcomes, not infrastructure:
- Checkout success rate ≥ 99.5%
- Order confirmation latency p99 ≤ 5 seconds at baseline (40k orders/day) and peak (480k orders/day)
- Search result latency p95 ≤ 1 second
- Payment authorization latency ≤ 2 seconds
- Price computation latency ≤ 200 ms
- Warehouse sync freshness ≤ 2 minutes end-to-end (vs. current 15 minutes)
- Cross-module data consistency: hourly reconciliation shows < 0.001% row-count discrepancy
**Error Budget and Rollback Policy**: Attach error budget to each SLO. When a service burns budget (or latency diverges > threshold during canary), its rollout stops automatically and flags revert without negotiation. Document policy explicitly; use during peaks without exception.
**Automated Rollback Controller**: Build system that monitors error rate and latency divergence during canary. On breach, gateway shifts traffic back and flags disable automatically. Fallback requires no human intervention. Test this automation in monthly game days.
**Dashboards**: Create per-service dashboards readable by tired engineers at 3 AM (traffic, errors, latency p50/p95/p99, database load). Create program dashboard showing progress against scope ladder, rung by rung.
5. Pricing Module: Rules Catalog and Golden-Master Characterization (Parallel with Data Platform) (depends on: 1, 2)
Catalog the 200k LOC pricing engine behavior before any extraction attempt. This is the foundational risk mitigation for the most complex module; it runs in parallel with data platform work (Step 7) because it is independent of infrastructure.
**Rules Discovery and Documentation**: Analyze and document all pricing rules in scope: country-specific logic (8 countries), currency handling (3 currencies), promotional rules, seasonal pricing, bulk discounts, loyalty point applications, regional variations. Create a living rules inventory.
**Historical Request Corpus**: Capture at least 1 million real historical pricing requests from production logs, covering all 8 countries, 3 currencies, 4 languages, all promotion types discoverable, edge cases, peak-season variations. Record exact inputs and outputs.
**Golden-Master Characterization Suite**: Build automated harness to replay corpus against monolith, capturing deterministic responses. This suite is the 'golden master': any new pricing service must match 100% of outputs. Suite becomes the automated gate for pricing extraction (Step 14).
**Test Data Expansion**: Supplement historical data with synthetic edge cases: multi-currency conversions, minimum purchase thresholds, conflicting promotions, time-based seasonal rules, inventory-driven pricing, customer-segment overrides.
**Dependency Mapping**: Explicitly document which customer attributes, product attributes, inventory levels, time-based factors, and external parameters affect pricing. Identify all cross-module dependencies that pricing currently reads from monolith (e.g., customer loyalty status from Customer module, product hierarchy from Catalogue module).
**Baseline Validation**: Run golden master against monolith to establish baseline passing rate. Document any non-deterministic behavior or race conditions found. This baseline is locked; no drift allowed during migration.
**CI Gate Definition**: Define hard rule: pricing service extraction cannot proceed until characterization tests pass 100% against both monolith and new service. Any divergence blocks ramp. This gate is not negotiable.
6. Seam-Level Verification: Golden Master, Contracts, Shadow Diffing, and Reconciliation (depends on: 2, 3)
Replaces impossible goal of blanket test coverage with verification exactly at the cut point. A 2M-line monolith cannot reach 70% coverage in a year; a service boundary can be verified to very high standard in weeks.
**Characterization Harness for All Services**: Build framework to record real production requests (anonymizing PII) and replay against monolith. Capture full responses as golden master. Every extracted service must pass golden master on its public API before taking live traffic. Output a diff report, not pass/fail.
**Consumer-Driven Contracts (Pact)**: Require contracts between monolith and each new service, and between services themselves. A change on one side breaks a build instead of waiting for production. Contracts versioned; breaking changes trigger explicit communication plan.
**Shadow Traffic and Response Diffing**: Mirror live requests to new service; compare responses field by field (not just status codes). Measure divergence rate continuously. Gate traffic ramp on divergence < 0.01% for 48 hours.
**Per-Module Data Reconciliation**: Build data reconciliation as first-class test, not afterthought. Compare row counts, checksums, and business invariants on hourly schedule. Owner assigned; alert threshold set. Reconciliation runs continuously during transition period (Stages A–C of cutover playbook).
**Synthetic Canary Transactions**: Implement real checkout, return, and search transactions executing every few minutes. Alert on functional regression before customers notice. Include multi-country, multi-currency variations.
**Explicit Non-Goal**: Do not pursue blanket line coverage of monolith. Track coverage only for newly written service code, target 80%. Seam-level verification replaces this impossible goal.
7. Data Platform: Schema Ownership, Join Elimination, CDC, Transactional Outbox, and Four-Stage Cutover Playbook (depends on: 2, 3)
The hardest and most under-specified part of most migrations. This work is independent of service extraction, so it starts in month 1 and runs in parallel. It is the foundation for reversible data transitions.
**Database-Enforced Ownership**: Assign every PostgreSQL table to exactly one module. Create one role per module, able to write only its own schema and to read others only through defined views. Database rejects cross-schema writes at the engine level, not by convention. Test this enforcement in CI.
**Stored Procedure Refactoring**: Inventory every stored procedure, attribute it to owning module. Either move logic into that module's application code or leave as module-private database function. After extraction, no stored procedure may touch two modules' tables.
**Cross-Module Join Elimination**: Eliminate cross-module joins one at a time, replacing each with an API call (preferred during cutover), an event-fed materialized read model, or a duplicated read-only projection. Track count per module; drive to zero before that module is extracted.
**Change Data Capture (CDC)**: Deploy Debezium reading PostgreSQL WAL into Kafka. This publishes monolith domain events with zero application change—lowest-risk start possible. Configure per-table CDC; test at peak load (480k events/day during 12x peak).
**Transactional Outbox Pattern**: For all new services, add outbox table. When service writes business state, it writes domain event atomically in same transaction. Outbox relay publishes to Kafka, ensuring no event loss. Implement poison-pill handling for failed publishes.
**Four-Stage Cutover Playbook (Reusable)**: Define one playbook applied identically every service extraction:
- **Stage A** (Shadow-Read): Service owns schema logically, reads from CDC into its own store, serves shadow traffic only. Monolith remains system of record; no cutover yet.
- **Stage B** (Read Cutover): Reads cut over to new service via flag. Monolith stays system of record via reverse-CDC replication. Rollback is flag flip + reconciliation pass.
- **Stage C** (Write Cutover): Writes cut over to new service. Monolith tables become read-only replicas fed by reverse CDC from service. Rollback is configuration change (flip sync direction) + reconciliation, not data restore.
- **Stage D** (Deletion): Old tables and dead code dropped only after module has survived one full peak (January or July) or four clean weeks, whichever is longer. Maintain 90-day read-only archive of old tables for regulatory retention and emergency queries.
**Reconciliation Service**: Build now (not later) so every cutover has objective consistency check. Compare row counts, business-invariant checksums, monetary totals hourly. Owner assigned; thresholds set. Mismatch is immediate rollback signal.
**Storage Migration Timeline**: New services start on existing cluster with own schemas. Physical database split (move to separate cluster) happens only once module is stable and proven at peak. This removes a critical-path blocker and allows parallelization.
8. Extract Catalogue and Search: Read-Heavy Pilot Service (depends on: 5, 6, 7)
First extraction, chosen because it is read-heavy, isolated, and carries no transactional risk. It also pays for itself: replacing nightly Lucene rebuild with real-time indexing is a visible business win that buys political cover for harder cuts.
**New Catalogue Service**: Create service owning product, category, media, and attributes tables. Build search API using Elasticsearch/OpenSearch with real-time indexing.
**CDC Feed**: Subscribe to CDC stream from monolith. ProductUpdated, PriceChanged, InventoryUpdated events trigger real-time search index refresh. Product availability reflects in search within < 60 seconds of change (vs. nightly rebuild).
**Shadow Traffic and Diff Validation**: Route requests through gateway behind feature flag. Run shadow mode: send requests to both monolith Lucene and new Search service; compare result sets field by field. Measure divergence; require < 0.01% for 48 hours before traffic ramp.
**Gradual Traffic Ramp**: 1% → 5% → 25% → 50% → 100% using feature flags and canary deployments. Rollback controller monitors latency and error rates; reverts flag if breach. Keep old Lucene index warm for two weeks post-cutover as rollback target.
**Mobile App Verification**: Verify mobile app behavior explicitly; it hits same endpoints. Test session persistence, offline search cache behavior, and app version compatibility during ramp.
**Four-Stage Playbook**: Execute Stages A–D as defined in Step 7. Stage A (shadow) lasts 1 week minimum. Stage B (read cutover) lasts 2 weeks. Stage C does not apply (reads only). Stage D (cleanup) after one peak or four weeks.
**Soak Period**: Land this extraction in open delivery window; soak at least four weeks before freeze (Dec 1 or June 1). No extraction reaches production less than four weeks before a freeze.
9. Extract Returns: Low-Stakes Proof of Four-Stage Playbook (depends on: 5, 6, 7)
Second extraction and first write-path proof. Returns is chosen because it is off peak-critical path, has modest coupling, and exercises full four-stage playbook at low risk. Primary output is a proven, reusable procedure, not just one service.
**Returns Service**: Build with own schema. Consume order and customer events rather than joining their tables. Implement return state machine: Requested → Approved → Shipped → Received → Refunded.
**Full Four-Stage Execution**: Apply Stages A–D end-to-end with explicit recorded game day validating each stage rollback path. Stage A (shadow reads) for 1 week. Stage B (read cutover) for 2 weeks. Stage C (write cutover) with reverse CDC. Stage D (cleanup) after one peak or four weeks.
**Rollback Rehearsal**: Before write cutover, execute full game day: simulate service failure mid-cutover, trigger rollback (reverse CDC, flag flip, reconciliation), verify all data consistent, re-run golden master, confirm back-office queries still work. Record this session; play back monthly.
**Back-Office Screens**: Keep back-office returns screens on monolith for now (staff workflow untouched). Returns service is API-only; back-office integration comes later (Step 18).
**Friction Point Capture**: Record every operational friction, process gap, and test hole discovered during extraction. Update playbook from learnings. This step is as much about process validation as about extracting Returns.
**Soak and Timing**: Execute in open window; soak returns service for minimum four weeks before any freeze. Gate to proceeding to Inventory (Step 10) is successful four-week soak with zero rollbacks and full reconciliation agreement.
10. Extract Inventory: Warehouse Sync Improvement and Reservation Semantics (depends on: 5, 6, 7)
Removes one of sharpest coupling points (15-minute file-exchange lag) and unblocks checkout work. Inventory runs in parallel with returns because it couples monolith to external warehouse system, not to other modules.
**Inventory Service**: Ingest warehouse feed directly (SFTP/API) instead of monolith polling. Design reservation semantics now: Reserve (place hold), Confirm (finalize after order), Release (cancel reservation on timeout/failure), with explicit timeout windows. Own stock levels and reservations per product per location.
**Parallel Feeds During Transition**: Run new ingest in parallel with legacy 15-minute feed. Reconcile hourly until both agree. This validates the new ingest does not miss updates or duplicate changes.
**Monolith Inventory Tables as Projection**: Keep monolith's inventory tables as read-only replicas fed by CDC from new service during Stage C (write cutover). Cart and checkout continue calling monolith queries unchanged during cutover; no checkout changes yet.
**Four-Stage Execution**: Apply Stages A–D. Stage A (shadow ingests and reads) for 2 weeks (must survive two 15-minute sync windows and validate no drift). Stage B (read cutover) for 2 weeks. Stage C (write cutover) with reverse CDC. Stage D (cleanup) after one peak.
**Peak-Load Testing**: Load-test inventory ingest at 12x (400k SKU updates/day during peak). Warehouse feed schedule and sales peaks do not always align; test worst-case concurrency. Validate no reservation deadlocks, no stock over-sells.
**Cutover Order**: Inventory read cutover must complete before Cart extraction (Step 13) to avoid monolith checkout calling new Inventory service via internal API during transition.
**Soak and Gate**: Soak minimum four weeks before freeze. Gate to proceeding to Customer (Step 11) is four-week soak with zero reconciliation mismatches and warehouse feed lag improved to < 2 minutes.
11. Extract Customer Accounts and Loyalty: Conservative Authentication Strategy (depends on: 9, 10)
Extracts customer identity, profile, and loyalty programs. Authentication is deliberately placed late and guarded hardest because auth failures derail e-commerce migrations most often.
**Customer Service**: Own profile, address, and loyalty tables. Implement country-specific loyalty rules (8 countries, different point accrual rates) as data-driven rules where possible, code where not. Design API: GetCustomer, UpdateProfile, GetLoyaltyBalance, RedeemPoints, AccruePoints.
**Authentication Strategy Phase 1**: Keep authentication (login) in monolith for now. Customer service exposes only data APIs; token issuance remains monolith's responsibility. This delays risky auth cutover; less risk to peak season.
**Distributed Session Handling**: Introduce Redis-backed distributed sessions. Services can verify customer identity without querying monolith database. Implement token-validation API so services can verify bearer tokens without round-tripping to monolith.
**Data Cutover**: Execute four-stage playbook. Stage A (shadow reads) for 1 week. Stage B (read cutover) for 2 weeks. Stage C (write cutover) for new customers, address updates, loyalty accrual. Stage D (cleanup) after one peak.
**Golden Master for All Countries**: Golden master captures customer queries across all 8 countries, all 4 languages, and all loyalty-rule variations. Shadow-traffic diff must show < 0.01% divergence before read cutover.
**Mobile App Session Behavior**: Test mobile app's long-lived sessions explicitly; storefront does not hold sessions same way. Validate token refresh, session timeout, and app version compatibility during cutover.
**Loyalty Accrual Last**: Move loyalty point accrual and redemption last within this step (Stage C final substep). Loyalty error is customer-visible financial error, not technical incident; guard hardest.
**Soak and Gate**: Soak minimum four weeks. Gate to proceeding to Cart (Step 13) is successful loyalty accrual cutover with zero customer complaints and full reconciliation agreement.
12. Extract Cart: Stateful Session Service (depends on: 6, 7, 10, 11)
Extract shopping cart, which is stateful and sits directly in front of checkout. Extracted before Pricing and Checkout because both depend on stable Cart boundary.
**Cart Service on Redis**: Build on Redis (or PostgreSQL with session affinity) for session and line-item state. Validate products and inventory through service API calls rather than direct database joins. Design API: AddItem, RemoveItem, UpdateQuantity, GetCart, ApplyCoupon, ClearCart.
**Idempotent Operations**: Every cart operation is idempotent. Retried add during peak does not duplicate line item. Retried remove is safe. Implement via unique constraint on (session, sku) or idempotency-key header.
**Monolith Cart Tables as Projection**: Keep monolith's cart tables as read-only projections fed by CDC from Cart service. Back-office screens continue reading old cart tables for abandoned-cart analytics (not yet migrated to service APIs in this step).
**Four-Stage Execution**: Apply Stages A–D. Stage A (shadow reads) for 1 week. Stage B (read cutover) for 2 weeks (use feature flag; gradual ramp 10% → 50% → 100%). Stage C (write cutover to service); Stage D after one peak.
**Business Metric Monitoring**: Cart latency surfaces as lost revenue (abandonment), not just error logs. Track cart abandonment rate and add-to-cart latency as primary success metrics during ramp.
**Anonymous vs. Authenticated Carts**: Test both paths separately; they follow different session-tracking mechanisms and fail in different ways. Ensure cart persists across login boundary.
**Soak Before Freeze**: Land in open window; soak minimum four weeks before freeze (Dec 1 or June 1). Gate to proceeding to Pricing (Step 14) is four-week soak with cart abandonment rate unchanged or improved and zero lost transactions.
13. Extract Pricing as Black Box Using Golden-Master Validation (depends on: 5, 6, 7)
Extract 200k LOC pricing logic as-is without rewriting. Rules are not understood by anyone, so wrap and characterize rather than refactor. Rule decomposition deferred to follow-up program in writing.
**Wrap Without Refactor**: Move pricing code into dedicated service, unchanged. Service owns pricing tables post-cutover. Expose single decision API: ComputePrice(customerId, productId, locationId, timestamp, quantityId, loyaltyStatus) → {price, applicablePromotions, taxes, currency}.
**Dependency Injection for Reads**: Refactor pricing's dependencies so it obtains customer data via Customer service API, product data via Catalogue service API, inventory via Inventory service API. No direct cross-module database joins.
**Golden-Master Validation**: Run characterization test suite (built in Step 5) against new service. Require 100% output match on all 1M historical requests across all 8 countries, 3 currencies, 4 languages, all promotion types, edge cases. Any divergence blocks ramp; no exceptions.
**Shadow Mode Duration**: Run shadow traffic against live pricing requests for minimum four weeks, comparing every computed price with monolith. Measure divergence continuously. Divergence > 0.001% blocks ramp.
**Gradual Cutover by Country**: Cut over per-country rather than all-at-once. Start with lowest-revenue country, validate four weeks per country, then ramp to others. Per-country flags allow independent rollback.
**Rollback Path**: Keep monolith's pricing evaluator available and warm as rollback target for at least one full peak (January or July) after cutover. Maintain ability to flip back to monolith pricing via feature flag without data restore.
**Four-Stage Playbook**: Stages A–D applied to pricing tables. Stage A (shadow) 4+ weeks. Stage B (read cutover) 2 weeks per country. Stage C (write cutover) per country. Stage D (cleanup) after one full peak.
**Deferred Refactoring in Writing**: Publish decision that pricing rule decomposition, DSL, and optimization are explicitly deferred to follow-up program after this migration stabilizes. Include this in all project communications and retrospectives.
14. Extract Payment: PCI-Strict Regime and Provider-by-Provider Cutover (depends on: 5, 6, 7)
Extract payment processing with stricter regime than any other service. Mistakes are irreversible and regulatory. Extracted before checkout orchestration because checkout cannot be decomposed without payment boundary.
**Payment Service**: Own integration with three payment providers (tokenization, authorization, capture, refund, provider webhooks). Design API: AuthorizePayment(idempotencyKey, amount, currency, cardToken, customerId) → {authorizationId, status}; CapturePayment(authorizationId); RefundPayment(captureId); HandleWebhook(webhookPayload).
**PCI Scope Reduction**: No raw card data at rest in service. Card data flows directly from client to provider (tokenization); only tokens stored in Payment service. Credentials in secrets management (Vault). No card data in logs or distributed traces.
**Idempotent Operations**: Explicit idempotency-key handling. Every payment request is idempotent; retries at peak are normal and must not double-charge. Implement via idempotency-key deduplication store (Redis with TTL).
**Provider-by-Provider Cutover**: Cut over one provider at a time (start with lowest-volume provider). Stage A (shadow) 2 weeks per provider. Stage B (read cutover, not applicable). Stage C (write cutover) for each provider, maintain fallback to monolith for other providers. Test each provider's decline, timeout, 3-D Secure, and chargeback scenarios explicitly.
**Golden Master Scenarios**: Golden master covers all three providers, all decline reasons, timeouts, partial authorizations, refund scenarios, chargebacks. Shadow traffic compares full payment outcomes (authId, status, amount, timestamp) before any live provider cutover.
**Fraud Detection and 3-D Secure**: These paths are usually least-tested and most visible when broken. Test explicitly; goldne master includes fraud-decline and 3-D Secure flows. Verify fraud rules and thresholds carry over unchanged.
**Fallback Orchestration**: Monolith retains ability to handle payment directly (as fallback) until second peak after Payment service cutover. Checkout can gracefully degrade to old payment path via feature flag if new service fails.
**Four-Stage Playbook**: Stages A–D per provider. Stage C (write) is highest-risk; ensure golden master passes 100% and shadow mode shows zero divergence before each provider cutover. Gate and soak strictly: four weeks minimum before any freeze.
**Soak and Timing**: Land in open window (Feb–May or Aug–Nov). Complete all three providers' Stage C cutover by month 9 to allow checkout orchestration time to soak before freeze.
15. Extract Orders: Event-Sourced Record of Truth (depends on: 9, 13, 14)
Extract order management as authoritative record of order lifecycle. Extracted after Inventory, Pricing, and Payment exist and are stable, because Orders depends on all three.
**Orders Service**: Own order tables and order state machine. Implement explicit state transitions: Pending → Confirmed → Preparing → Shipped → Delivered, with validation blocking invalid transitions. Design API: CreateOrder(cartId, customerId, paymentAuthorizationId), GetOrder(orderId), CancelOrder(orderId), UpdateOrderStatus.
**Event Sourcing**: Record all order state changes as immutable events. Build order state from event log on demand. Audit trail satisfies regulators and fulfillment teams; state can be rebuilt after incidents. Include: OrderCreated, PaymentAuthorized, InventoryReserved, OrderConfirmed, OrderPreparing, OrderShipped, OrderDelivered, OrderCancelled.
**Event Consumption**: Consume events from Payment service (PaymentAuthorized, PaymentFailed), Inventory service (StockReserved, ReservationCancelled), and Returns service (ReturnInitiated, RefundIssued) rather than polling or joining.
**Four-Stage Playbook**: Stages A–D. Stage A (shadow) for 1 week. Stage B (read cutover) for 2 weeks, with gradual flag ramp. Five teams that query orders start reading from Orders service via API. Stage C (write cutover): new orders written to Orders service; monolith order tables become reverse-CDC read-only replicas. Stage D after one peak.
**Reconciliation: Monetary and Row-Count**: Reconcile order counts and monetary totals hourly against monolith throughout transition. Currency totals must match exactly (cent-by-cent); row count discrepancies are immediate rollback. Implement automated reconciliation query; owner assigned; threshold zero.
**Concurrent Order Transitions**: Load-test concurrent order state transitions at 480k/day peak. Order state machine becomes serialization point for distributed system; ensure no race conditions, no duplicate orders, no lost transactions.
**Soak Before Checkout**: Complete Orders cutover (Stages A–C) by month 9. Soak minimum four weeks before freeze. Gate to proceeding to Checkout (Step 16) is four-week soak with zero monetary reconciliation mismatches and zero order duplicates.
16. Extract Checkout: Distributed Saga Orchestration (Highest Risk) (depends on: 12, 13, 14, 15)
Highest-risk extraction, deliberately placed last among transactional work and only after components it orchestrates are individually proven at scale. This step composes independent services into coherent checkout flow.
**Checkout Orchestrator Service**: Build service that coordinates checkout: cart validation, price computation, inventory reservation, payment authorization, order creation. Design as explicit saga with named steps and compensating actions.
**Saga Orchestration**: Implement synchronous saga (single coordinator) or asynchronous (choreography via events), chosen based on latency testing (target checkout p99 < 5 seconds at peak). Synchronous preferred for checkout because customer waits; failure is visible. Steps:
1. Validate cart via Cart service
2. Compute price via Pricing service (cached if < 1 second old)
3. Reserve inventory via Inventory service
4. Authorize payment via Payment service
5. Create order via Orders service
**Compensating Transactions**: For every step, define compensation:
- Step 3 fails: Release inventory reservation
- Step 4 fails: Release inventory reservation, void authorization (if possible)
- Step 5 fails: Release reservation, void authorization, return payment to customer
- Step 2 recomputes and differs: Increase price, reject order; or decrease price, accept at old price (business rules decision, document explicitly)
**Idempotency End-to-End**: Checkout request includes idempotency key (unique per browser session + timestamp). Service deduplicates on this key. Retried checkout cannot double-charge or double-reserve; returns previous result.
**Timeout Handling**: Inventory reservation expires in 15 minutes (configurable). Payment authorization valid for 7 days (provider-specific). Order creation never times out; if hanging, manually investigate. Saga must fail safe to retryable state, never to half-committed order.
**Shadow Traffic Before Live**: Mirror live checkout traffic (100% of checkout requests during business hours) to new orchestration for minimum 2 weeks before any live cutover. Compare full outcomes: order ID, order total, inventory reservations, payment authorization IDs, error messages. Divergence > 0.001% blocks live cutover.
**Live Ramp During Open Window**: Ramp live traffic only during open delivery window (Feb–May or Aug–Nov). Gate and soak strictly: minimum four weeks before freeze. Keep monolith checkout path fully functional and warm (receiving live traffic via feature flag) as rollback target until Checkout service has survived one full peak.
**Peak-Readiness Gate Mandatory**: Hold six-week peak-readiness gate (Step 19) before proceeding to back-office migration (Step 18). Failed gate stops this work immediately and defers to next window.
17. Migrate Back-Office, Storefront, and Mobile Clients to Service APIs (depends on: 16)
Moves 300 back-office staff and client applications off monolith database direct access. Until this step, monolith database remains live dependency even where logic moved.
**Back-Office Screen Refactoring**: Migrate screens table by table. Replace direct SQL with service API calls through gateway. Start with orders (call Orders service), then customers (call Customer service), then inventory (call Inventory service). Build aggregation endpoints: /orders/{id}/full-details calls Orders + Payments + Inventory + Returns services, caches 30 seconds, returns unified response.
**Aggregation Endpoints and Caching**: Services are now call-chain away, not co-located. Back-office latency would suffer without caching. Implement short-lived cache (TTL 30 seconds) for frequently accessed data (customer profiles, recent orders). Graceful degradation: if one service slow, show cached data and alert staff.
**Storefront and Mobile App**: Both hit same endpoints (via gateway). Update storefront (server-rendered) to call service APIs while keeping old path functional behind feature flag; rendering regression becomes flag flip, not rollback. Mobile app points at gateway for migrated endpoints; keep old endpoints alive for un-updated app versions (users do not upgrade on schedule). Implement API versioning: v1 (legacy monolith), v2 (service APIs); clients request version in Accept header.
**API Versioning and Deprecation Windows**: Publish versioning rules: breaking changes trigger major version bump (v2 → v3). Old version supported for minimum 90 days after major release. Client teams must upgrade within window; do not force upgrade. Document deprecation timeline in API spec.
**Load Test Back-Office Concurrency**: Test 300 concurrent staff on top of peak storefront (480k orders/day). New services now carry both loads; autoscaling and database connection pools must handle burst. Simulate realistic staff queries: order searches, customer history, bulk refunds.
**Distributed Tracing for Debugging**: Every back-office request traced across services. Staff can view trace in UI; operations team can see which service was slow. Trace includes: request start, service calls, database queries, cache hits/misses.
**Monitoring and Runbooks**: Create runbooks for common issues: slow customer search (check Customer service load), payment lookup fails (check Payment service), order create fails (check Orders service latency). Link from dashboard to runbook.
**Gate to Monolith Decommissioning**: Back-office must be fully migrated (no direct SQL reads to monolith) before monolith core decommissioning (Step 18). This step completes organizational cutover.
18. Chaos Engineering, Resilience Testing, and Pre-Peak Validation (depends on: 17)
Validates new distributed architecture survives failure scenarios and peak load without cascading collapse. This step is as much about proving state is coherent as about finding failure modes.
**Chaos Game Days**: Scheduled monthly (or before each peak). Kill each service in turn (Search, Inventory, Orders, Payments, etc.); confirm storefront degrades gracefully (e.g., 'Search temporarily unavailable, catalog browsing still available') rather than failing completely. Kill database replicas; verify service continues with read-only or cached data. Kill message broker; verify no events lost and no reordering. Record each game day; publish findings and mitigation actions.
**Peak-Readiness Gate (Before Each Peak)**: Run six weeks before January and July peaks (mid-November, mid-May):
- **12x Load Test**: Generate realistic 480k orders/day traffic against production-shaped data (8 countries, 3 currencies, 4 languages, realistic product hierarchy). Measure checkout p99 < 5 seconds, search p95 < 1 second, payment < 2 seconds.
- **Capacity Headroom**: Confirm all services autoscale to handle 12x baseline. Database connection pools have headroom. Message broker partitions are sufficient. Cache hit rates do not collapse under load.
- **Rollback Rehearsal**: Execute full rollback of most recent service extraction in load-test environment. Measure rollback time; must be < 30 minutes including data reconciliation.
- **Error Budget Review**: Confirm SLO error budgets not burned significantly. If burned, identify culprit and mitigate before peak.
- **Evidence Publication**: Publish load-test results, capacity headroom metrics, rollback time, and SLO status. Gate is pass/fail; failed gate defers peak exposure and triggers root-cause work.
**Full System Load Test**: All services under load simultaneously. Measure inter-service latencies, database load, message broker throughput. Identify bottlenecks: pricing calculations, search queries, payment provider round-trip time, inventory reservations under concurrent access. Tune:
- Database query indexes
- Connection pool sizes
- Caching strategies
- Message broker partitions
- Service autoscaling thresholds
**Failure Mode Analysis**: Identify top 10 single-point-of-failure risks:
1. Payment provider outage → graceful degradation (pre-authorize smaller amounts?)
2. Inventory service down → checkout blocked; mitigation: cache inventory in checkout orchestrator
3. Pricing service down → checkout blocked; mitigation: cache last-known prices
4. Orders service down → checkout blocked; mitigation: queue orders in Kafka, replay when service recovers
5. Database down → all services blocked; mitigation: read-only replicas for queries
6. Message broker down → no events published; mitigation: outbox patterns ensure no event loss
7. API gateway down → all traffic blocked; mitigation: active-active gateway setup (two regions or multiple providers)
8. Warehouse sync delayed → inventory stale; mitigation: alert threshold, manual intervention process
9. Customer service down → login blocked; mitigation: cache tokens, allow anonymous checkout
10. Search service down → browsing blocked; mitigation: fallback to category list without search
For each failure, document mitigation (architectural change or operational procedure), test in chaos game day, and update runbooks.
**Synthetic Transaction Monitoring**: Implement real-world checkout, return, and search transactions executing every five minutes. Alert on failure before customers notice. Include multi-country, multi-currency variations.
**Performance Baseline Documentation**: Document baseline latencies (checkout, search, payment) at baseline load (40k orders/day). Load test must show no regression at peak; improvements accepted. Document these baselines in runbooks for operations team reference.
19. Monolith Decommissioning and Steady-State Operations (depends on: 18)
Safely retire monolith code once all services stable and production-proven. This step is final validation that new architecture is coherent; incomplete decommissioning signals hidden coupling.
**Module-by-Module Cleanup**: Delete extracted service code from monolith only after that service has survived one full peak (January or July, whichever comes first) or four clean weeks post-cutover, whichever is longer. Before deletion:
- Audit dead code: which stored procedures, views, tables, methods are no longer called
- Verify service API is the only interface for data owned by extracted module
- Confirm no service calls back into monolith code
- Delete extracted logic and dependencies
**Database Decommissioning**: Dropped tables are archived (not deleted) for 90 days (regulatory retention and emergency queries). After 90 days, drop and archive to long-term storage. Monolith database shrinks as modules extracted. When monolith becomes shell (mostly unused), decide: keep as fallback or shut down entirely.
**Cross-Module Stored Procedures**: All stored procedures touching multiple modules' tables must be eliminated before monolith shutdown. If any remain, move logic into services or refactor. Document any that cannot be moved; escalate as risk.
**Backup and Recovery Procedures**: Shift from single monolith snapshot to per-service snapshots. Each service team owns backup/recovery for their database. Document recovery procedures: which services recover in which order, which can tolerate data loss vs. which require point-in-time recovery. Test recovery monthly.
**Architectural Decision Records**: Publish final ADRs documenting:
- Why services were split at these boundaries
- What problems each split solved
- What trade-offs were made
- What cross-service communication patterns emerged
- What monitoring and alerting proved most useful
**Operational Runbooks**: Finalize runbooks for each team:
- Incident response: common failure modes, resolution steps, escalation paths
- Deployment procedures: how to deploy service, rollback procedure, expected latency
- On-call procedures: alert thresholds, page-worthy events, war room communication
- Database procedures: backup, restore, schema migrations, connection pool tuning
**Service Ownership Model**: Confirm each of five teams owns one or more services end-to-end:
- Codebase and CI/CD pipeline
- Database schema and migrations
- On-call rotation and SLOs
- Production incidents
- Capacity planning and scaling
No shared ownership; clear escalation paths between teams.
**Team Ramp-Down of Migration Work**: Migration enablement squad (formed in Step 1) transitions into steady-state platform team. Reduce migration velocity; redirect capacity to feature work on services.
**Exit Criteria and Project Close**:
- All rungs 1–6 of scope ladder complete (or deliberately stopped at rung boundary)
- Both peak seasons (January and July) survived without migration-caused incidents
- All services deployed independently by month 12
- Monolith reduced to < 5% of original codebase or decommissioned entirely
- All architectural decisions documented and team alignment confirmed
**Celebrate and Document Lessons**: Publish retrospective capturing:
- What went well: which techniques proved most valuable (golden master? chaos testing? soak periods?)
- What was hard: which services took longer, which risks materialized
- What would change next time
- Which rungs of scope ladder were reached and why work stopped where it did
**Deferred Work**: Explicitly list architectural or optimization work deferred to follow-up programs (e.g., Pricing DSL refactoring, read-write split at database level, multi-region deployment).
20. Peak Season Validation and Post-Peak Stabilization (depends on: 18, 19)
Proves new architecture survives peak and validates migration is truly complete. January and July peaks are the final test; this step verifies readiness and documents learnings.
**Pre-Peak Confirmation**: One week before peak start (Dec 25 for January peak, June 25 for July peak), confirm:
- All peak-readiness gate checks passed
- All services healthy and responding normally
- Database connection pools at capacity
- Cache hit rates normal
- Message broker lag within SLOs
- On-call rotations staffed
- War room communication channels open
**Peak Monitoring**: During peak (480k orders/day sustained for 2–3 weeks), maintain heightened monitoring:
- Every service dashboard visible in central war room
- Latency p99, p95, p50 trending in real time
- Error rate per service alarmed
- Database query performance monitored
- Message broker lag tracked
- Payment success rate watched (fraud filters, authorizations)
- Inventory reservation accuracy validated hourly
**Incident Response**: Any incident < 5 min MTTR automatically escalates to war room. Team lead validates:
- Root cause (service slow? database? payment provider?)
- Impact (customer-visible? checkout blocked? data corruption?)
- Mitigation (rollback flag? scale service? throttle traffic?)
- Recovery (how long to resolve?)
**Post-Peak Retrospectives**: Within one week of peak completion, each service team retrospectives on:
- Peak traffic patterns observed vs. load-test simulations
- Any incidents: root cause, time-to-detect, time-to-recover
- Performance variations: which services scaled, which became bottlenecks
- Data accuracy: any reconciliation mismatches discovered during peak
- Lessons for next peak
**Capacity Planning**: After peak, analyze:
- Database query times at peak: any unexpected slowdowns?
- Service autoscaling: did services scale early enough? were there cascading failures?
- Cache effectiveness: hit rates at peak vs. baseline
- Message broker: any message loss or reordering?
- Payment provider latency: did provider response times increase during peak?
**Final Validation**: Confirm scope ladder rung achieved:
- Rung 6 complete: back-office migrated, monolith core reduced, checkout orchestration stable
- Teams deployed independently during peak (or blocked from deploying due to freeze, which is correct)
- Zero unplanned downtime caused by migration
- All rollback procedures worked in chaos testing; never needed in production
**Program Closure**: Publish final evidence:
- Peak season metrics (order volume, success rate, latency, errors)
- Service-by-service stability (uptime, incidents, MTTR)
- Scope ladder rung reached
- Explicit deferred work list
- Team feedback and lessons learned
**Next Program Planning**: If rung 7+ desired (e.g., Pricing rules DSL refactoring, multi-region deployment), plan as separate 6-month program. Document in writing; do not creep scope into current program.
Note on proposal 2: Proposal 2 provides the strongest foundation: explicit calendar constraints (Dec 1–Jan 15, June 1–July 15 freezes), scope ladder concept, four-stage cutover playbook, and data platform as a distinct critical track that starts in month 1.
Adopted: Step 1 (Program Setup): Adopted calendar and freeze windows (Dec 1–Jan 15, June 1–July 15) wholesale; this is the binding constraint in the brief and Proposal 2 makes it explicit and non-negotiable.
Adopted: Step 2 (Architecture Map): Adopted table-to-module enforcement via ArchUnit and SQL linters; the insight that boundary slippage must be enforced at CI level (not review) is crucial for a five-team monorepo.
Adopted: Step 3 (Delivery Platform): Adopted blue-green deployment and feature-flag kill-switch as primary rollback mechanisms; adopted golden-path templates to accelerate service extraction.
Adopted: Step 6 (Seam Verification): Adopted golden-master characterization harness and explicit policy to not pursue blanket monolith line coverage (80% target for new code only is pragmatic).
Adopted: Step 7 (Data Platform): Adopted four-stage cutover playbook end-to-end; this single reusable framework (Shadow-Read → Read Cutover → Write Cutover → Deletion) is the highest-leverage insight in Proposal 2, eliminating ad-hoc cutover decisions.
Adopted: Step 7 (Reconciliation as First-Class Test): Adopted hourly reconciliation with thresholds and owners; a mismatch is immediate rollback signal, not a ticket. This removes ambiguity about data correctness.
Adopted: Scope Ladder Concept: Adopted the explicit ranked rungs; slippage means stopping at rung boundary, not mid-increment. This is the correct framing for a 12-month constrained program.
Rejected: Service extraction sequence (Steps 8–16): While Proposal 2's order is sound (Search → Returns → Inventory → Customer → Cart → Pricing → Payment → Orders → Checkout), it underemphasizes the foundational work in data platform (Step 7) and pricing characterization (Step 5 in my proposal). Proposal 2 bundles both into step 7 and step 13 implicitly; I separate them as Step 5 (Pricing Rules Catalog, parallel in month 1) and Step 7 (Data Platform) to remove false dependencies and start cataloging pricing rules immediately rather than waiting for platform readiness.
Rejected: Step 1 Organization Aspect: Proposal 2's Step 1 mentions 'set capacity budget' but does not explicitly articulate team restructuring toward service-aligned ownership or clarify when teams transition from business-function teams to stream-aligned (service) teams. This organizational change is substantial and deserves explicit step planning (included in my S1 expansion).
Rejected: Mobile App Versioning Strategy: Proposal 2's Step 17 mentions keeping old endpoints alive for un-updated app versions but lacks detail on API versioning policy, long-lived session handling, and app distribution contingencies. This is a material risk for e-commerce: mobile app users do not upgrade on company schedule, and session mismatches between old and new API can lose carts. I expand this in my S17.
Rejected: Warehouse Sync Improvement Detail: Proposal 2's Step 10 states improving from 15 minutes to < 2 minutes but does not detail parallel ingestion during transition or reconciliation procedure to validate new ingest does not miss updates. I add explicit parallel-feed validation as a transition mechanism in my S10.
Rejected: Chaos Engineering Emphasis**: Proposal 2 mentions chaos testing late (implied in step 4, explicit only in step 18). Resilience testing of critical paths (checkout, payment, inventory) should start earlier and be reinforced multiple times. I elevate chaos engineering to a dedicated step (S18) with explicit game-day schedule and failure-mode analysis before first peak.
Note on proposal 1: Proposal 1 is comprehensive and detail-rich on testing strategy and peak-season protection but creates unnecessary serialization through 20-step dependency chains where parallelization is possible (Search extraction should not wait for Pricing characterization).
Adopted: Step 4 (Peak Season Protection): Adopted 6-week freeze windows (4 weeks before + 2 weeks during peaks); 'soak before freeze' rule (no production changes < 4 weeks before freeze) is essential and Proposal 1 articulates it clearly.
Adopted: Step 5 (Pricing Module Characterization): Adopted explicit black-box golden-master baseline from characterization test suite covering all 8 countries, 3 currencies, 4 languages, all promotion types. The framing 'characterization tests become the golden master' is precise and operationalizable.
Adopted: Step 6 (Test Coverage Improvement): Adopted targeted coverage goal (70%+ for extract-candidate modules, 80% for new service code) and gates blocking extraction below 60%. The insight that mutation testing verifies test quality (not just line coverage) is valuable.
Adopted: Step 11 (Saga Pattern Framework): Adopted explicit compensating-transaction framework and idempotency-key handling end-to-end. The distinction between choreography and orchestration is valuable framing for checkout complexity.
Adopted: Step 18 (Load Testing and Peak Capacity Validation): Adopted multi-stage load testing (base → ramp → sustain → spike → degrade) with realistic user-behavior simulation and per-service bottleneck analysis. The failure-mode analysis (top 10 risks) is a useful template.
Rejected: 24-Step Serialization (actuallt 20 steps): Proposal 1's dependency chain creates artificial critical-path length. For example, Step 8 (Test Coverage Improvement) depends on Step 3 (Domain Analysis), but test coverage for Search can begin in parallel with Pricing characterization; they are independent. My proposal parallelizes Pricing characterization (S5) as month-1 work independent of data platform (S7).
Rejected: Test Coverage to 70%**: Proposal 1 sets target 70%+ coverage for all extracted services. A 2M-line monolith cannot reach this for all modules in 12 months without consuming entire engineering budget. The golden-master characterization at seam level (Proposal 2's insight) is superior and more pragmatic: 100% coverage at the API boundary via replay, 80% for new code in services.
Rejected: Pricing Characterization Step Placement**: Proposal 1 embeds pricing characterization in Step 14 (late in sequence). This creates false dependency: pricing rules can be cataloged in month 1 as parallel work (my S5) independent of deployment platform; there is no reason to wait until Step 14 to start understanding the 200k LOC rules.
Rejected: Phase 2 Refactoring Scope Creep**: Proposal 1 mentions Phase 2 refactoring of pricing rules (DSL, decomposition) within the current 12-month window. This is scope creep into the most complex, least-understood module during a freeze-constrained program. Proposal 2 and my proposal explicitly defer rule decomposition to follow-up program.
Rejected: Monolith Database Decommissioning Sequencing**: Proposal 1's Step 21 (Decommissioning) happens before load testing (Steps 22–24) and team reorganization (Step 19). This removes rollback target while architecture is unproven. Correct order is: load test with rollback available, prove at peak, then decommission only after stability demonstrated.
Note on proposal 3: Proposal 3 distills best insights (golden master, black-box pricing, DDD, CDC, anti-corruption layer) into 12 steps but compresses too much: peak-season protection, dual-write complexity, and team reorganization are underspecified; lacks month-by-month calendar.
Adopted: Step 1 (Team Alignment and Service-First Pods): Adopted the framing of reorganizing teams from business-function (Pricing team, Fulfillment team) to service-aligned (Search Service team, Orders Service team) as foundational change. Proposal 3 articulates this early.
Adopted: Step 2 (DDD and Domain Boundaries): Adopted event-storming workshops and explicit 'Coupling Heatmap' to identify most entangled modules before extraction. This is more rigorous than static code analysis alone.
Adopted: Step 4 (Golden Master Characterization)**: Adopted 'Input Logging' and 'Replay Engine' concept: record production requests, replay against both old and new systems, diff responses. This is simpler and lower-cost than building comprehensive test suites from scratch.
Adopted: Step 7 (Anti-Corruption Layer)**: Adopted framing of CDC + Outbox as 'anti-corruption' boundary: services read events from monolith (CDC), write their own events (Outbox), but never write back to shared monolith schema. This language clarifies the unidirectional dependency.
Adopted: Step 9 (Pricing Black Box)**: Adopted 'Encapsulation without Refactoring' for 200k LOC module: move code as-is, replace dependencies with interfaces (API calls), validate via golden master, defer rule decomposition to follow-up program. This is high-risk-mitigation through conservatism.
Rejected: 10-Step Compression Without Calendar**: Proposal 3 distills into 10 actionable steps but sacrifices critical operational detail. Freeze windows (Dec 1–Jan 15, June 1–July 15) mentioned only in Step 1 ('Freeze Windows' defined but no month-by-month delivery calendar). Proposal 2's explicit calendar is essential for a 12-month migration with two peaks.
Rejected: Dual-Write Complexity Underspecified**: Proposal 3's Step 7 ('Anti-Corruption Layer') mentions outbox pattern but does not detail four-stage cutover playbook (Stage A shadow, Stage B read, Stage C write, Stage D delete). Without explicit stages, teams will invent inconsistent cutover approaches. My proposal (and Proposal 2's) four-stage playbook eliminates ambiguity.
Rejected: Rollback Procedures Not Explicit**: Proposal 3 lacks rollback charter concept (expand/contract migrations, feature flags, rehearsed game days). Step 12 mentions 'chaos engineering' but does not specify when rollback rehearsals happen or how often. Proposal 2's explicit requirement ('every increment ships a feature-flag kill switch and a recorded game-day rehearsal') is operationally clearer.
Rejected: Returns Service Not Explicitly Extracted**: Proposal 3's Step 11 mentions 'Admin Panel' / 'Management Service' vaguely but does not extract Returns as first write-path proof (as Proposal 2 Step 9 does). Returns is the ideal low-stakes service to validate the four-stage playbook before Inventory and Orders. My proposal (S9) makes this explicit.
Rejected: Ordering: Checkout Before Payment**: Proposal 3 Step 10 (Checkout Orchestrator) comes before Step 9 (Payment service). Checkout cannot be decomposed without payment boundary already working; checkout's saga needs to call Payment API. Proposal 2 correctly orders Payment (Step 14) before Checkout (Step 16). My proposal maintains this order (S14 Payment before S16 Checkout).
Rejected: Mobile App Strategy Absent**: Proposal 3 does not address long-lived mobile app sessions, API versioning, or app distribution delays (un-updated app versions). This is material risk for e-commerce but is completely absent in Proposal 3. Proposal 2 (Step 17) and my proposal (S17) address this explicitly.
Note on proposal 1: Proposal 1 articulates pricing characterization and peak-season protection clearly but underestimates how completely data platform work (join elimination, CDC, outbox, four-stage playbook) must precede service extraction.
Adopted: Peak Season Protection Comprehensiveness: Proposal 1's Step 4 is the most complete freeze-window articulation in any proposal: 6-week freeze, 4 weeks before + 2 weeks during, plus rollback runbooks < 30 minutes, incident escalation plan. Adopted wholesale and referenced in my S1.
Adopted: Pricing Characterization as Foundational: Proposal 1 makes explicit that characterization test suite must be built before pricing extraction and becomes CI gate. This is the correct risk mitigation and is adopted in my S5 (separated as parallel, month-1 work).
Adopted: Dual-Write Strategy Detail: Proposal 1's dual-write and 2-week validation post-cutover concept is sound. Adopted in my four-stage cutover playbook (Stage C write cutover, then 2–4 week soak in Stage D before deletion).
Adopted: Load Testing Multi-Scenario Approach: Proposal 1 details chaos testing (kill services, fail databases, degrade gracefully) more explicitly than other proposals. This emphasis on 'no cascading failures' is valuable and I amplify in my S18.
Rejected: Pricing Characterization Placement (Step 14 Late): While Proposal 1 recognizes its importance, embedding it within the pricing-extraction step (S14 in Proposal 1) means cataloging pricing rules is deferred until later in the program. This is inefficient: rule analysis is independent of platform readiness and should start in month 1 (my S5). The false dependency removes parallelization opportunity.
Rejected: Three-Sentencde Test Coverage Requirement Underspecified: Proposal 1's Step 6 says 'target 70%+ coverage for extract candidates' but does not specify how to measure or enforce this across a 2M-line codebase. Golden-master seam-level verification (Proposal 2's approach, adopted in my S6) is more practical: 100% API coverage via replay, 80% line coverage for new code.
Rejected: Service Extraction Sequence Criticality Underappreciated**: Proposal 1's sequence is valid but does not emphasize why Inventory (S9 in Proposal 1, S10 in Proposal 2) must be extracted before Cart (S14 in Proposal 1, S12 in Proposal 2). Cart calls Inventory API to check stock; if Inventory not extracted yet, Cart still calls monolith, creating false progress. Proposal 2's explicit dependency edges (e.g., 'Extract Cart depends on Extract Inventory') are more rigorous.
Note on proposal 2: Proposal 2 is the strongest proposal provided and forms the foundation of my improved plan. Its explicit calendar, scope ladder, four-stage playbook, and table-ownership enforcement set it apart.
Adopted: Every major structural decision from Proposal 2 is adopted: calendar (Dec 1–Jan 15, June 1–July 15 freezes), scope ladder (rungs 1–6 core objective, 7+ optional), four-stage cutover playbook (Shadow-Read, Read, Write, Delete), peak-readiness gate (6 weeks before each peak), seam-level verification (golden master, contracts, shadow diffing, reconciliation), table-ownership enforcement (ArchUnit, SQL linters), and mid-program re-planning point (month 6).
Adopted: I did not substantially reject any major concept in Proposal 2, only refined by adding: (1) explicit Pricing Rules Catalog (S5) as parallel month-1 work to separate it from data platform readiness dependency, (2) more detail on team restructuring timing (expanded S1), (3) more explicit mobile app versioning strategy (expanded S17), (4) earlier emphasis on chaos engineering (dedicated S18 before peak-readiness gate), and (5) more explicit warehouse-sync improvement procedure with parallel-ingestion validation (S10).
Rejected: No substantial rejections of Proposal 2 approach. The proposal is operationally sound and calendar-aware. Only refinements made where the original was sound but could be more explicit or parallelized differently.
--- PROPOSAL 2 (agent deepseek-flash_refine_2, deepseek/deepseek-flash) ---
Estimated complexity: high
Success metrics: - Independent deployability: at least 4 of the 5 teams release their own artefact without coordinating with another team by month 5, and all 5 by month 9.
- The 30-minute maintenance window is retired by month 6; no release after that date requires a planned outage.
- Deployment lead time from merge to production is 30 minutes or less for a service, and each team releases at least 3 times per week by month 6.
- Zero unplanned downtime attributable to the migration across the 12 months; availability of 99.95% or better inside each peak window.
- Both January and July peaks pass with no migration-caused incident: 12x baseline load sustained, checkout p99 under 5 seconds, error rate under 0.5%, no queue backlog beyond 5 minutes.
- 100% of migration increments that reach production have a rollback demonstrated in a game day and executable in under 30 minutes.
- The rollback controller reverts a canary automatically on error-rate or latency divergence, proven in at least two live rehearsals per open window.
- Hourly reconciliation shows under 0.001% discrepancy on row counts and checksums per module; zero unexplained business-invariant violations; a monetary mismatch triggers automatic rollback.
- Cross-module joins and cross-module writes originating in application code are zero for every module at the moment it is extracted, enforced by database roles and CI rather than by review.
- Stored procedures touching more than one module's tables: zero for every extracted module.
- Pricing parity: 100% agreement with the golden master on a corpus of at least 1,000,000 historical requests across all 8 countries, 3 currencies and 4 languages, both before and after cutover.
- Search freshness improves from a nightly rebuild to under 30 seconds between a product change and its visibility in search results.
- Warehouse inventory freshness improves from 15 minutes to under 2 minutes end to end.
- Customer auth: zero forced logouts during cutover for both storefront and mobile clients, and no version of the mobile app in the field breaks at any point in the program.
- The checkout transaction remains inside the monolith through both peaks; the saga deferral is documented, accepted and signed off before month 12.
- The peak-readiness gate is passed with published evidence six weeks before both peaks, covering 100% of its defined checks.
- Scope ladder rungs 1–8 are complete within 12 months, or the program stops at a rung boundary in a documented, coherent, peak-safe state.
Steps (18):
1. Calendar-first charter, scope ladder and peak-readiness protocol
The binding constraint in this objective is the commercial calendar, not the technology, so the calendar is decided before anything else. Everything later obeys it.
- Declare the hard freezes against the real sales calendar, in the shape 1 December – 15 January and 1 June – 15 July. Inside a freeze only rollback-enabling and hardening changes ship.
- Reserve four 'risky cut' slots per year, roughly March–April and September–October. February, May, August and November are soak and hardening months and carry no new cutover.
- Forbid any cutover step from starting within six weeks of a freeze. Every cutover must end in a freeze-ready state: both paths live, flags reversible, reconciliation green.
- Publish the scope ladder. Rungs 1–8 are the core objective; rungs 9+ are optional. Slippage stops at a rung boundary in a coherent, peak-safe state, never mid-increment.
- Write the rollback charter: expand/contract schema change, feature-flag kill switch and a game-day rehearsal recorded before go-live.
- Write the abort criteria: the conditions under which the program stops, and who signs off.
- Create a migration enablement squad of six engineers on rotation from the five teams. It owns the platform, the shared cuts and the risky shared data work.
- Budget 40–50% of the five teams' capacity for migration and staff the ladder to that budget rather than filling the year.
2. Executable architecture map, table ownership and boundary enforcement (depends on: 1)
Five teams committing to one repository will silently re-couple anything that is separated and not policed, so enforcement is part of the map, not a later step.
- Run distributed tracing on the monolith for four weeks before drawing any boundary. Real call paths beat static imports for finding true coupling.
- Build a table-to-module and query-to-module map by parsing every SQL statement, ORM mapping and stored procedure, cross-checked against the database's own query logs.
- Assign each of the 350 tables to exactly one owning module. Tables nobody can own are declared contested and scheduled into S7.
- Score each candidate service on coupling, transactional risk, change frequency and peak-path criticality. This ranking drives the extraction order, not intuition.
- Add ArchUnit rules that fail the build on new cross-module Java dependencies, and a SQL linter that fails on cross-module joins and writes. Existing violations are frozen into a baseline file that may only shrink.
- Publish the target service list, the owning team per service and the reasoning as ADRs.
- Re-rank the scope ladder at the month-six review using what the map actually showed.
3. Delivery platform: per-module pipelines, gateway, feature flags, environments (depends on: 1, 2)
No module is extracted until its team can deploy, flag and route on its own.
- Kubernetes namespaces, quotas and autoscaling policies sized for 12x peaks.
- API gateway in front of the monolith from day one as the strangler entry point. Storefront, mobile and back-office traffic all flow through it even while it routes everything to the monolith.
- One CI/CD pipeline and one environment per module. The monolith keeps its pipeline for hotfixes until S5 replaces it.
- A feature-flag service, with every new call path flag-guarded. Flags are the primary rollback instrument for the whole program.
- Golden-path templates for a new service: build, pipeline, observability, health checks, flag integration, database migration tool.
- Two permanent environments: a production-shaped soak environment and a load-test environment able to generate 12x traffic.
- Secrets management and per-environment configuration so behaviour changes never require a monolith redeploy.
4. Observability, business SLOs and the automated rollback controller (depends on: 3)
A canary is only trustworthy if it is judged automatically, so the rollback promise is built once here and reused by every later step.
- Centralised logging, metrics and distributed tracing, with trace correlation across gateway, monolith and every service.
- Instrument the monolith's blind spots: query latency by module, connection-pool saturation, Lucene rebuild duration, warehouse file-exchange lag.
- Define SLOs on business outcomes: checkout success rate, order confirmation p99, search latency, payment authorisation rate, price computation latency, warehouse sync freshness.
- Attach an error budget to each SLO. When a service burns budget, its rollout stops and its flags revert automatically. No negotiation during a peak.
- Build the rollback controller: on error-rate or latency divergence during a canary, the gateway shifts traffic back and disables flags without human action.
- Per-service dashboards a tired engineer can read at 03:00, plus one program dashboard showing progress against the scope ladder.
5. Split the deployment unit and retire the 30-minute maintenance window (depends on: 2, 3)
This is the cheapest large win in the program and it delivers the headline objective — independent deployability — before any process separation, by splitting the build and the release train while the code still runs together.
- Split the single artefact into one build per owning module with a shared parent.
- Allow modules to be released as separate artefacts on the existing runtime first. Independent deployability is a build and release property long before it is a topology property.
- Retire the two-week coordinated release train. Each team gets its own pipeline, cadence and on-call rota, with the gateway and schema compatibility as the contract between teams.
- Adopt expand/contract database migrations so schema and code changes no longer have to ship together.
- Replace the maintenance window with blue-green deployment on two identical stacks, traffic switched at the gateway and rollback performed by switching back.
- Publish the measurement: deployment lead time, deployment frequency per team, and the share of releases that needed no coordination with another team.
6. Seam-level verification: golden master, contracts, shadow diffing and reconciliation (depends on: 2, 3)
A two-million-line monolith cannot reach blanket coverage in a year. Verification is aimed exactly where the cut will be made, which is where it is affordable and where it actually pays.
- Build a characterization harness that records real production requests and responses, anonymised, as a golden master. This is the safety net for every extraction.
- Require every extracted service to pass the golden master on its public API before it takes live traffic, producing a diff report rather than a pass/fail.
- Consumer-driven contract tests between the monolith and each new service, and between services, so a breaking change breaks a build rather than production.
- Shadow traffic mirroring live requests to the new service with field-by-field comparison. The traffic ramp is gated on the divergence rate.
- Per-module data reconciliation as a first-class test: row counts, checksums and business invariants on a schedule, with an owner and an alert threshold.
- Synthetic canary transactions that run a real checkout, return and search every few minutes and alert on functional regression before customers notice.
- Track line coverage only for newly written service code, where the target is 80%. Blanket coverage of the monolith is explicitly not a goal.
7. Data platform: schema ownership, join elimination, CDC, outbox and the four-stage cutover playbook (depends on: 2, 3, 6)
The hardest part of the program, and the part that does not depend on service extraction, so it starts in month one and runs in parallel with everything else.
- Enforce ownership inside the database: one PostgreSQL role per module, able to write only its own schema and read others only through defined views. Cross-schema writes are rejected by the database, not by convention.
- Inventory every stored procedure, attribute it to one module, and either move it into that module's code or leave it as a module-private function. After a module is extracted, no stored procedure may touch two modules' tables.
- Eliminate cross-module joins one at a time, replacing each with an API call, an event-fed read model or a duplicated read-only projection. Track the count per module and drive it to zero before that module is cut.
- Stand up change data capture with Debezium reading the PostgreSQL WAL into Kafka. This publishes monolith domain events with no application change, the lowest-risk start available.
- Add a transactional outbox for new services so their events and their state changes commit together.
- Adopt one reusable four-stage cutover playbook and apply it identically every time. Stage A: the service owns its schema logically, reads from CDC into its own store and serves shadow traffic only. Stage B: reads cut over, the monolith stays system of record. Stage C: writes cut over and the monolith's tables become read-only replicas fed by reverse CDC. Stage D: old tables and dead code are dropped only after a full peak or four clean weeks, whichever is longer.
- Make stage C genuinely reversible: because the sync direction can be flipped, rolling back a write cutover is a configuration change plus a reconciliation pass, not a data restore.
- Build the reconciliation service once, here, so every later cutover has an objective consistency check with thresholds and owners.
- Deliberately defer the 1.2 TB physical split. Services start on the existing cluster in their own schemas; physical separation is post-program work.
8. Rung 1 — Extract Catalogue and Search (depends on: 5, 6, 7)
The first extraction: read-heavy, mostly isolated, no transactional risk. It also pays for itself, because replacing the nightly Lucene rebuild with real-time indexing is a visible business win that buys political cover for the harder cuts.
- Create a Catalog service owning product, category and media tables plus its own search index.
- Feed it from CDC so product and price changes appear in search within seconds instead of after a nightly rebuild.
- Route through the gateway behind a flag and ramp 1% → 5% → 25% → 50% → 100%, with the rollback controller able to revert to the monolith's internal Lucene path at any point.
- Run shadow traffic and compare result sets before any live traffic, then keep the old index warm for two weeks after full cutover.
- Include the mobile app in the same ramp, since it hits the same endpoints.
- Land this cut in a risky-cut slot and let it soak at least four weeks before the freeze.
9. Rung 2 — Extract Returns, the first write path (depends on: 5, 6, 7)
Second extraction and the first that owns writes and a database. Returns is chosen because it is off the peak-critical path, has modest coupling, and exercises the full four-stage playbook at low stakes.
- Build the Returns service with its own schema, consuming order and customer events rather than joining their tables.
- Run the playbook end to end: shadow reads, read cutover, then write cutover with reverse CDC keeping the monolith's tables current.
- Prove the rollback path in a game day before write cutover, including a reconciliation pass and a re-run of the golden master.
- Keep the back-office returns screens on the monolith for now, so staff workflow is untouched by this step.
- Record every friction point and correct the playbook. The real output of this step is a proven, reusable procedure, not just one service.
10. Rung 3 — Extract Inventory and retire the 15-minute warehouse file exchange (depends on: 5, 6, 7)
Removes one of the sharpest coupling points in the system and unblocks the checkout work. Inventory couples the monolith to an external warehouse process rather than to other modules, so it can run in parallel with the other early cuts.
- Build the Inventory service to ingest the warehouse feed directly and publish stock-level events.
- Preserve the existing file-based interface for the first weeks, running the new ingest in parallel with the legacy feed and reconciling hourly until they agree.
- Keep the monolith's inventory tables as an event-fed projection, so cart and checkout keep working unchanged during the cut.
- Design reservation semantics now — reserve, confirm, release, with expiry — even though checkout is not yet extracted. The API is needed later and is cheap to get right here.
- Load-test inventory ingest at 12x, because the warehouse feed schedule and the sales peaks do not always coincide.
- Cut over reads first, then writes, with the rollback controller able to restore the file feed as the source of truth.
11. Rung 4 — Extract Customer Accounts and Loyalty with a conservative auth strategy (depends on: 5, 6, 7, 9)
Customer accounts and loyalty, including the authentication decision. Auth is the step that most often derails e-commerce migrations, so the auth path is deliberately moved last and guarded hardest.
- Build the Customer service owning profile, address and loyalty tables, with country-specific loyalty rules expressed as data where possible and as code where not.
- Keep authentication in the monolith for the first phase. Move token issuance only once customer data is stable, and never within four weeks of a freeze.
- Introduce distributed session handling and a token-validation API so services can verify identity without querying the monolith database.
- Cut over reads, then writes, with reverse CDC, validating against the golden master across all 8 countries and 4 languages.
- Verify the mobile app's session behaviour explicitly, since it holds long-lived sessions the storefront does not.
- Move loyalty point accrual and redemption last, because a loyalty error is a customer-visible financial error, not a technical incident.
12. Rung 5 — Extract Cart (depends on: 8, 10, 11)
The cart is stateful and sits directly in front of checkout. It is done before pricing because the checkout path needs a stable cart boundary to call.
- Build the Cart service on Redis for session and line-item state, validating products and inventory through service calls rather than database joins.
- Make every cart operation idempotent, because a retried add or remove during a peak must not duplicate a line item.
- Keep the cart tables in the monolith as a read-only projection fed by events, for rollback and for the not-yet-migrated back-office screens.
- Ramp traffic while monitoring cart abandonment rate as the business metric, since cart latency shows up as lost revenue rather than as errors.
- Exercise anonymous and authenticated carts separately; they follow different paths and fail in different ways.
- Land this cut in a risky-cut slot with a full four-week soak before the freeze.
13. Rung 6 — Extract Pricing and Promotions as an unchanged black box (depends on: 5, 6, 7)
Extracts the 200,000-line pricing module without rewriting it. The rules are not understood by anyone, so they are wrapped and characterized rather than reverse-engineered. Rule decomposition, documentation and a DSL are explicitly out of scope for these twelve months.
- Build a golden master corpus from at least a million real historical pricing requests and their recorded outputs, covering all 8 countries, 3 currencies, 4 languages, plus every promotion type that can be discovered.
- Invert the module's dependencies rather than its logic: pricing obtains customer, product and inventory data from event-fed read models it owns, not from synchronous fan-out to three services. A fan-out on the price path is the wrong shape at 12x peak.
- Move the pricing code into its own service unchanged, owning its tables after cutover, and expose a single decision API.
- Run it in shadow mode for at least four weeks against live traffic, comparing every computed price with the monolith. Any divergence blocks the ramp.
- Cut over behind a flag with per-country ramps, since a pricing error is a financial and legal exposure in each jurisdiction rather than a technical incident.
- Keep the in-monolith evaluator available and warm as the rollback path for at least one full peak after cutover.
- State in writing that rule decomposition is deferred to a follow-up program, so it does not creep back into this one.
14. Rung 7 — Extract Payment under a stricter regime than anything else (depends on: 5, 6, 7)
Payment mistakes are irreversible and regulatory, so this module gets the strictest controls in the program.
- Build the Payment service owning the integration with the three providers: tokenisation, authorisation, capture, refund and provider webhooks.
- Reduce PCI scope rather than expand it. No raw card data at rest in the new service, credentials in secrets management, no card data in logs or traces.
- Make every payment operation idempotent with explicit idempotency keys, because retries at peak are normal and double charges are not recoverable.
- Cut over provider by provider rather than all three at once, starting with the lowest-volume provider.
- Run the golden master across all decline, timeout, partial-authorisation and refund scenarios, and rehearse the fallback to the monolith's direct provider integration.
- Verify fraud detection and 3-D Secure paths explicitly, since they are usually the least covered and the most visible when they break.
- Land this cut early in a risky-cut slot so it soaks well before the freeze.
15. Rung 8 — Extract Order Management with an explicit state machine (depends on: 9, 10, 13, 14)
Order management becomes the record of truth for the order lifecycle, after the services it depends on exist and are stable.
- Build the Order service with its own database and an explicit order state machine that validates every transition.
- Introduce event sourcing for order status so the audit trail satisfies regulators and fulfilment teams, and so state can be rebuilt after an incident.
- Consume events from payment, inventory and returns rather than polling or joining.
- Cut over reads first for the five teams that query orders, then writes, keeping the monolith's order tables as a reverse-CDC projection.
- Reconcile order counts and monetary totals hourly against the monolith throughout the transition. A monetary mismatch is an immediate rollback, not a ticket.
- Load-test concurrent order state transitions at peak, since the state machine becomes the new serialisation point.
16. Keep the checkout transaction in the monolith for the first peak, and decide on the saga afterwards (depends on: 12, 13, 14, 15)
This is the deliberate difference from the obvious plan. Checkout is the single highest-risk cut and it sits directly on the peak-critical path. A distributed saga across pricing, inventory, payment and orders buys elegance at the cost of the two things the brief protects most: January and July sales.
- Thin the monolith's checkout into a synchronous orchestrator that calls the Pricing, Inventory, Payment and Order services through the gateway.
- Implement compensation inline in the orchestrator — a failed authorisation releases the reservation, a failed order creation voids the authorisation — without introducing a general saga framework.
- Propagate idempotency keys end to end so a retried checkout cannot double-charge or double-reserve.
- Handle the peak case explicitly: when inventory or pricing is slow, checkout must fail to a retryable state, never to a half-committed order.
- Require the peak-readiness gate before the cut that makes checkout depend on remote calls. A failed gate is a stop, not a delay; the monolith stays authoritative.
- Review after a full peak whether the orchestrator is worth extracting as a saga-based Checkout service. That decision belongs to the follow-up program, with peak data in hand.
- Document and sign off the deferral, so it is an accepted design choice rather than an unfinished step.
17. Migrate the back-office, storefront and mobile clients off the monolith database (depends on: 16)
Until the clients move, the monolith's database stays a dependency even where the logic has already left.
- Refactor back-office screens to consume service APIs through the gateway, replacing direct SQL access table by table, starting with orders and customers.
- Add aggregation endpoints where a screen needs several services, plus a short-lived cache so 300 staff do not multiply load on the new services.
- Update the server-rendered storefront to call service APIs while keeping the existing rendering path working behind a flag, so a rendering regression is a flag flip rather than a rollback.
- Point the mobile app at the gateway for migrated endpoints and keep the old endpoints alive for un-updated app versions. No version of the app in the field may break at any point in the program.
- Publish API versioning rules and deprecation windows so teams can change their services without coordinating with client releases.
- Load-test the back-office with 300 concurrent staff on top of peak storefront traffic, since the two now share services.
18. Decommission the extracted modules, validate the second peak, write the exit report (depends on: 17)
Removes what is left and proves the new architecture survives a peak. This step is as much about proving the state is coherent as about deleting code.
- Delete dead code and dropped tables module by module, only after a module has run a full peak or four clean weeks, whichever is longer.
- Keep read-only access to the old database for a defined period for historical and regulatory queries, then archive and decommission it.
- Replace the monolith's remaining cross-module reads with service calls or event-fed projections. The monolith should now be a small set of modules plus the checkout orchestrator.
- Re-run the full 12x load test against the new topology across all 8 countries, 3 currencies and 4 languages, and tune autoscaling, connection pools and broker partitions from the results.
- Run chaos game days: kill each service in turn and confirm the storefront degrades gracefully rather than failing completely.
- Confirm and publish the peak-readiness gate evidence before the second peak. A failed gate defers remaining work rather than risking the peak.
- Write the exit report: final service boundaries, data ownership, runbooks, SLO history, the scope-ladder rung actually reached, and the list of work explicitly deferred to a follow-up program.
Note on proposal 1: Technically rich and well sequenced, but it spends the engineering budget on an unachievable coverage target and treats rollback of data as a consequence rather than the central design constraint.
Adopted: The peak-season freeze framework with explicit rollback runbooks (Step 4) — a 6-week freeze with rehearsed rollback is the right shape and I keep it.
Adopted: Shadow traffic with response comparison before ramping live traffic (Step 8/9) — it is cheap, objective evidence and it gates every ramp in my plan.
Adopted: Extract pricing as-is first and refactor later (Step 15 phase 1) — the instinct not to rewrite rules nobody understands is correct.
Adopted: Keeping read-only access to the old database after cutover (Step 21) — cheap insurance, and I extend it to a full peak rather than two weeks.
Rejected: Step 6's goal of raising monolith coverage from 25% to 70% across Search, Inventory, Customer, Cart and Payments — a 2-million-line monolith will not reach that in twelve months, and the same effort spent on golden-master and contract verification at the extraction seam buys far more safety.
Rejected: Step 11, building a saga orchestration framework before payment extraction (Step 12) — it introduces a distributed transaction on the checkout path a full window before payment has been independently proven, so I extract payment first and defer the saga entirely.
Rejected: Step 20, decommissioning the monolith and dropping tables before the second-peak load test (which runs at Step 22) — that removes the rollback target while the new topology is still unproven.
Note on proposal 3: The sharpest of the three on pricing and on data movement, but it compresses a 12-month two-peak program into 12 steps and never reconciles its sequencing with the calendar.
Adopted: The golden-master replay engine comparing old and new responses (Step 4) — this is the single most valuable testing idea in the round and it is the safety net for every cut in my plan.
Adopted: Per-country ramps for the pricing cutover (Step 9) — a pricing error is a legal exposure per jurisdiction, so country-by-country ramping is right.
Adopted: Replacing the nightly Lucene rebuild with real-time indexing (Step 5) — this reframes an extraction as a business win and buys political cover for the risky cuts.
Adopted: The 'Checkout Orchestrator' with compensation (Step 10) — adopted but moved out of this 12-month window and placed behind the peak gate.
Rejected: There is no month-by-month calendar and peak-season protection is compressed into a single final step (Step 12) — the brief's hardest constraint is January and July sales, and this plan schedules Pricing (S9) and Checkout (S10) with no freeze protection around them.
Rejected: Step 7's instruction that new services read from read-only replicas of the legacy database — that keeps every service coupled to the monolith's schema and defeats the point of transferring ownership, so I replace it with CDC-fed per-service stores.
Rejected: Step 11's 'Final Monolith Decomposition' drops extracted tables and deletes monolith code before any peak has run against the new topology — I hold each drop until the module has survived a full peak or four clean weeks.
--- PROPOSAL 3 (agent qwen3.8-flash_refine_3, alibaba/qwen3.8-flash) ---
Estimated complexity: high
Success metrics: 1. Zero unplanned downtime during the 12-month migration and subsequent peaks.
2. Peak season (Jan/Jul) capacity maintained at 12x baseline with no performance degradation in checkout flows.
3. 100% of Pricing and Promotion transactions match the Golden Master characterization tests post-extraction.
4. Five teams deploying independently at least once per week without coordination conflicts.
5. All monolith-to-service data synchronization latency under 2 seconds (near real-time).
6. Database size reduced by >40% through extraction and cleanup of legacy unused tables.
7. Search index refresh time reduced from 24 hours (nightly) to < 1 minute (real-time).
Steps (16):
1. Program Governance, Peak Calendar, and Scope Ladder
Establish the binding constraints of the program before any technical work begins. The calendar dictates that the January and July sales peaks are immovable objects; therefore, all migration steps must be scheduled around them.
2. Platform Foundation: Kubernetes, Gateway, and Observability (depends on: 1)
Deploy the infrastructure layer required to run services independently and observe traffic flow. This includes a Kubernetes cluster for workloads, an API Gateway as the central routing control point, and a full observability stack (Tracing, Metrics, Logs). The Gateway is the primary mechanism for rollback via traffic shifting.
3. Data Foundation: CDC, Outbox Pattern, and Transactional Events (depends on: 1, 2)
Implement Change Data Capture (Debezium) and a Transactional Outbox pattern in the monolith. This creates the event backbone required for eventual consistency and allows new services to subscribe to monolith changes without touching the legacy code logic. This step runs in parallel with platform setup.
4. Architectural Decoupling: Table Ownership and Anti-Corruption Layer (depends on: 2)
Define strict ownership for the 350 tables and implement an Anti-Corruption Layer (ACL) to intercept cross-module dependencies. This involves creating separate database schemas or logical boundaries for high-coupling areas like Orders and Catalogue to prepare for physical separation.
5. Characterization Test Harness: The Golden Master (depends on: 2, 3)
Build a replay engine and capture a 'Golden Master' corpus of production traffic. This automated test suite records request/response pairs from the monolith, creating a baseline for validation. This is critical for the Pricing module and high-traffic endpoints where refactoring is impossible.
6. First Extraction Pilot: Catalogue and Search (Read-Heavy) (depends on: 3, 4, 5)
Extract the Catalogue and Search services. These are low-risk (read-heavy) and validate the strangler fig pattern. Implement real-time search indexing via CDC events, replacing the nightly Lucene rebuild. Use the Golden Master to verify product data and search results match the monolith.
7. Second Extraction: Inventory Synchronization (depends on: 3, 5)
Extract Inventory management, specifically handling the integration with the external warehouse system (15-minute sync). This removes a critical dependency from the monolith and enables real-time stock visibility. The service acts as the single source of truth for stock levels.
8. Third Extraction: Customer Profile and Identity (depends on: 3, 4)
Extract Customer Accounts and Profile management. Move authentication logic and customer data ownership to a dedicated service. Ensure the Mobile App and Storefront can authenticate against the new service while maintaining session compatibility via JWT or shared session state.
9. Pricing Module Stabilization: Black Box Extraction (depends on: 5)
Extract the 200,000 LOC Pricing and Promotions module as a 'Black Box' service. Do not refactor the logic; wrap it. Use the Golden Master to validate 100% accuracy across all 8 countries and complex promotion rules. This step is strictly scheduled outside of any peak season.
10. Core Transactional Extraction: Orders and Order Management (depends on: 6, 7, 8, 9)
Extract the Order Management domain, including order creation, state machines, and lifecycle tracking. This service acts as the consumer of events from Inventory, Pricing, and Customer services. It replaces the monolith's direct order processing logic.
11. Checkout Orchestration and Saga Implementation (depends on: 7, 9, 10)
Implement the Checkout Service, acting as the orchestrator (Saga) for the payment process. It coordinates the distributed transaction across Cart, Pricing, Inventory, and Payments. It handles compensating transactions (e.g., releasing inventory on payment failure) to ensure data consistency.
12. Payment Provider Integration Service (depends on: 10, 11)
Extract the logic responsible for connecting to the three payment providers. This service handles authorization, capture, and refunds. By isolating this, the monolith no longer holds sensitive payment processing logic, reducing PCI scope and coupling.
13. Return and Refund Workflow Extraction (depends on: 10, 12)
Extract the Returns and Refunds logic. This service consumes order events to trigger return workflows, updates inventory, and requests refunds from the Payment Service. This completes the reverse logistics capability as a microservice.
14. Legacy Monolith Decommissioning: Strangler Finish (depends on: 10, 11, 12, 13)
Remove the extracted logic from the monolith. The monolith is now a legacy shell containing only the storefront rendering layer (which delegates to APIs) and potentially the Back-Office (if not yet migrated). This step involves rigorous cleanup of unused code and database tables.
15. Back-Office Migration and Staff Tooling (depends on: 14)
Migrate the Back-Office (300 staff users) to use the new service APIs. This may involve a dedicated BFF (Backend for Frontend) service that aggregates data from Orders, Customers, and Inventory for the staff UI, replacing direct database joins in the monolith.
16. Operational Handover and Autonomous Team Setup (depends on: 15)
Finalize team ownership. Each of the five teams is assigned to specific services (e.g., Team A owns Inventory and Search, Team B owns Orders and Checkout). Transfer on-call rotations and disaster recovery runbooks to the new services.
Note on proposal 1: Excellent on technical detail and test coverage, but too linear and ignores the 'Deployment Unit' split as a prerequisite for independent team velocity.
Adopted: Adopted the 'Black Box' strategy for Pricing (S5/S9) to mitigate risk of complex rule logic.
Adopted: Adopted the strict 'Peak Season Protection' calendar (S1) to ensure no risky changes happen during Jan/Jul.
Adopted: Adopted the 'CDC and Event Driven' infrastructure (S3) as the foundation for data synchronization.
Rejected: Rejected 'Step 8: Test Coverage 70%' as a hard metric for the whole monolith; it is unrealistic for 2M lines in 12 months. Adopted 'Golden Master/Characterization' for critical paths instead.
Rejected: Rejected extracting 'Orders' (S10) before 'Inventory' and 'Pricing'; the saga requires the components to exist.
Note on proposal 2: The most strategically sound regarding data and testing rigor, correctly identifying 'Golden Master' and 'Table Ownership' as key enablers.
Adopted: Adopted 'Step 6: Seam-level Verification' (S5 in my plan) using Golden Master/Shadow traffic for validation.
Adopted: Adopted 'Step 7: Data Platform' strategy, enforcing table ownership and CDC.
Adopted: Adopted the 'S1: Program Setup' governance model which prioritizes the freeze windows.
Adopted: Adopted the 'S5: Split Deployment Unit' concept, though I merged the infrastructure aspects into S2/S4 for brevity in this plan.
Rejected: Rejected the sequencing of 'Extract Catalogue (S8)' as the first extraction. While good, 'Inventory (S7)' was moved earlier in my plan because it's a hard dependency for Cart/Checkout and has a specific file-sync bottleneck to fix.
Rejected: Rejected 'Step 16: Compose Checkout' as the very last step; it must happen after all components (Pricing, Inventory, Customers) are stable, which aligns with my S11, but I added S12 for Payments to decouple 3rd party risk.
Note on proposal 3: Good structural approach to the Strangler Fig pattern but underestimates the complexity of the 'Checkout' transactional flow by skipping a dedicated Payment service extraction.
Adopted: Adopted the clear separation of 'Catalogue/Search' (S6) as a low-risk pilot.
Adopted: Adopted the concept of 'Mobilization' (S1) to set the calendar first.
Adopted: Adopted the 'Inventory' extraction (S7) as a key enabler for real-time stock.
Rejected: Rejected the 'Checkout Orchestrator' (S10 in proposal 3) which calls Payment logic directly. It is safer to extract a dedicated 'Payment Service' (S12) to wrap the 3 providers and isolate PCI concerns from the Orchestrator.
Rejected: Rejected leaving 'Inventory and Customer' extraction until step 8/6 of the proposal; they are prerequisites for the Pricing/Order complex interaction.
You do not know which of them was voted for, and you must not guess it: judge them on their merits. Your answer has these parts:
- "summary": two or three sentences on what the final round offers, as a whole.
- "assessments": one object per final proposal, with "proposal" (its number), "fitness" ("strong", "adequate" or "weak" for the task as stated), "strengths" and "weaknesses" (lists of concrete points: steps, order, metrics, realism, risk handling).
- "ranking": the numbers of the final proposals from best to worst.
- "ranking_reasons": why that order, naming what separates each one from the next.
- "versus_initial": one object per initial proposal, comparing YOUR FIRST CHOICE with it: "proposal" (its number in round 0), "verdict" ("better" if your first choice is better than that initial proposal, "worse" or "similar"), "why" and "how" (in what concrete ways).
- "improved_over_initial": true if your first choice is better than EVERY initial proposal.
- "improvement_summary": what the deliberation added or lost with respect to the initial proposals, overall.
- "process_evaluation": an evaluation of the process itself, not a narration: whether the convergence between agents was earned by better arguments or was mere imitation, whether the agents criticised each other's ideas or just copied them, whether anyone questioned the task's premises, and what was lost along the way.
- "process_issues": a list of concrete problems you observed in the process.
- "suggestions": a list of concrete changes that would make the process produce a better plan.
[VOTE COMPARISON]
[SYSTEM]
You are an expert reviewer of multi-agent planning processes.
Several LLM agents drafted plans for a task, refined them over a number of rounds while seeing each other's proposals, and finally voted for the best one.
Be exhaustive but precise: name concrete steps, ideas and metrics, never generalities. Judge plans by their fitness for the task as stated, their realism, their completeness, the soundness of their order and dependencies, how measurable their success is and how they handle things going wrong.
You are an impartial evaluator, not a chronicler: assess the proposals and the process on their merits, never rationalise what happened or assume that the outcome was right.
After your analysis, answer in the requested structure.
Every text field you write will be read by a busy person, so write for them: short sentences, one idea each, in short paragraphs. Text fields accept Markdown: separate paragraphs with a blank line, use a bullet list when you enumerate things and plain paragraphs when you explain or argue, and bold at most one key phrase per paragraph. A text of more than three sentences must be split into paragraphs; never deliver a single unbroken block of text.
[HUMAN]
Task given to the agents: "A mid-size European fashion retailer runs its e-commerce on a 10-year-old monolith: Java 8 / Spring, about 2 million lines, one PostgreSQL database of 1.2 TB with 350 tables and heavy use of stored procedures and cross-module joins. It serves 8 countries, 3 currencies and 4 languages, with about 40,000 orders a day and peaks of 12x during sales. The monolith contains: the storefront (server-rendered, plus a separate mobile app hitting the same endpoints), catalogue and search (a Lucene index rebuilt nightly), pricing and promotions (the most complex module, 200,000 lines, with country-specific rules nobody fully understands), cart and checkout with three payment providers, order management, inventory synchronised every 15 minutes with the warehouse system via file exchange, customer accounts and loyalty, returns, and a back-office used by 300 staff. Deployments happen every two weeks as a single artefact with a 30-minute maintenance window; test coverage is 25% and mostly unit tests. Five teams of 8 developers, each organised around a business area but all committing to the same repository.
Plan the migration to independently deployable services over 12 months with no feature freeze, no unplanned downtime and the ability to roll back every step, preserving the peak-season capacity (sales in January and July must not be put at risk)."
You assessed the proposals of the final round without knowing the vote, and ranked them from best to worst as: 2, 1, 3. Your reasons were:
Proposal 2 is ranked first because it brilliantly separates deployment independence (Step 5) from logical service extraction, and takes the safest possible stance on the Checkout Saga by deferring its extraction to protect the peaks. Proposal 1 is a close second, offering exceptional detail on the four-stage cutover and parallel pricing work, but it risks the second peak by extracting the Checkout Saga in Step 16. Proposal 3 is ranked last due to a critical sequencing error (Checkout before Payment) and a lack of operational rigor around data cutover and rollbacks.
The vote is now revealed. Each voter received the same final proposals and chose one:
claudeHaiku4.5_voter_1 (anthropic/claude-haiku-4-5) voted for proposal 1. Justification: Proposal 1 is the most complete and rigorous plan. It explicitly makes the calendar a binding constraint (Step 1), defines hard freeze windows and peak-readiness gates before each risk, structures work into six rungs with deliberate stop points to prevent mid-increment slippage, includes 18+ success metrics covering all aspects (business outcomes, technical precision, rollback verification, team autonomy), details 20 comprehensive steps with explicit dependencies, and includes mandatory game-day rehearsals and chaos testing for every extraction. Most critically for the stated objective, it fully addresses how to preserve peak-season capacity by building peak-readiness gates six weeks before peaks, defining clear rollback procedures for every step, and ensuring soak periods of at least four weeks before freezes. Proposals 2 and 3 both have merit, but Proposal 2 defers checkout saga extraction beyond the 12-month window, and Proposal 3 conspicuously omits explicit freeze windows and peak-readiness gates despite the brief stating the calendar is a 'binding constraint'—a disqualifying gap for a migration where January and July sales 'must not be put at risk.'
deepseek-flash_voter_2 (deepseek/deepseek-flash) voted for proposal 1. Justification: Proposal 1 is the most complete and internally coherent: its 20 dependency-linked steps cover platform, data (CDC/outbox/four-stage cutover), seam-level verification, rollback automation, chaos testing and explicit peak-readiness gates, and its success metrics are the most precise and measurable (pricing parity on 1M+ requests, reconciliation thresholds, rollback <30 min, 12x peak SLAs). It also matches the brief's core constraints—calendar-first scheduling, no feature freeze, reversible every step, and protected January/July peaks—without the thinner coverage seen in Proposal 3. Proposal 2 is a strong contender with a sensible deferral of the checkout saga, but Proposal 1's greater depth and explicit rollback/reconciliation machinery make it the safer, more complete plan.
qwen3.8-flash_voter_3 (alibaba/qwen3.8-flash) voted for proposal 2. Justification: Proposal 2 is superior because it correctly identifies that a full distributed checkout extraction cannot realistically survive the January and July peak seasons within a 12-month window. By deliberately keeping the checkout transaction inside the monolith as a synchronous orchestrator for the first year, it perfectly aligns with the non-negotiable requirement to preserve peak capacity and avoid unplanned downtime during sales, whereas Proposal 1's timeline is dangerously optimistic and Proposal 3 lacks the necessary architectural detail and risk mitigation strategies.
The selected plan is proposal 1 (2 of 3 votes).
Your answer has these parts:
- "agrees": true if the selected plan is your first choice, false otherwise.
- "comment": two to five sentences confronting the vote with your ranking. If they differ, say on which criteria the voters and you weigh the proposals differently, and whether the voters' justifications reveal a bias (length, confidence, style, position in the list). If they agree, say whether the voters' justifications rest on the same merits you found or on others. Do not revise your ranking.
[ROUND 0]
{"round_summary": "The agents proposed three migration strategies with distinct strengths. **None fully address the 12-month timeline** given the massive codebase.\n\n* Proposal 1 is the most realistic regarding peak-season risks but delays extraction.\n* Proposal 2 establishes a strong platform foundation but fatally delays team reorganization.\n* Proposal 3 handles the pricing module pragmatically but lacks granular database details.\n\nOverall, **all plans lack sufficient detail on data migration runbooks** for the database.", "proposals": [{"proposal": 1, "summary": "This plan outlines a 24-step process starting with extensive documentation and test coverage improvements before any code extraction. It extracts services incrementally, beginning with read-heavy modules like Search and moving to complex domains like Pricing and Checkout.\n\nThe strategy heavily relies on dual-write patterns and strict rollback procedures to protect peak sales seasons. However, **increasing test coverage to 70% before extraction** will likely consume too much of the 12-month timeline.", "approach": "**Methodical, risk-averse**, documentation-heavy extraction."}, {"proposal": 2, "summary": "This proposal details a 15-step plan that establishes a Kubernetes platform and strangler fig facade before extracting any services. It leverages Change Data Capture and event streaming to decouple the database early in the process.\n\nThe plan concludes with team reorganization and monolith decommissioning after extracting core transactional flows. **Delaying team reorganization to step 14** is a critical flaw that will cause organizational friction during the migration.", "approach": "**Platform-first**, strangler-pattern driven migration."}, {"proposal": 3, "summary": "This strategy uses a 10-step framework centered on event storming and a robust data platform utilizing the Outbox pattern. It treats the complex Pricing module as a black box wrapped in characterization tests to avoid rewriting unknown rules.\n\nThe extraction order prioritizes read-only pilots before moving to stateful domains like Cart and Checkout. While pragmatic, **the 10-step high-level approach** lacks the granular dependency mapping required for a 1.2 TB database.", "approach": "**Domain-driven**, black-box legacy wrapping."}]}
[ROUND 1]
{"round_summary": "The agents significantly improved their plans by adopting each other's strongest strategic insights. They all converged on a black-box extraction for the pricing module.\n\nThey also agreed on using Change Data Capture for database decoupling. The proposals are now much closer in structure, though Proposal 2 stands out for its rigorous handling of constraints.", "converging": true, "proposals": [{"proposal": 1, "assessment": "improved", "what_changed": "The proposal reduced its step count and significantly improved its sequencing by adopting the black-box pricing strategy. It fixed the overly serialized dependency chain of its previous version by parallelizing read-heavy extractions. However, it still retains a somewhat rigid, linear progression compared to the adaptive approach of Proposal 2.", "improvements": ["Adopted explicit CDC and transactional outbox patterns for data synchronization.", "Introduced the black-box pricing extraction with a golden master characterization test suite.", "Improved sequencing by extracting Search and Catalogue earlier as a read-heavy pilot."], "regressions": ["Still relies on a rigid linear dependency chain rather than a calendar-driven scope ladder.", "The goal of raising test coverage to 70% for extract-candidate modules remains overly optimistic."], "taken": [{"from_proposal": 2, "steps": [2, 13], "what": "Platform foundation with Kubernetes and CDC for event-driven data sync.", "why": "Adopted to establish a robust technical baseline and cleaner data synchronization."}, {"from_proposal": 3, "steps": [4, 7], "what": "Pricing module as a black box with golden master tests and real-time search indexing.", "why": "Adopted to mitigate the massive risk of rewriting unknown pricing rules."}], "rejected": [{"from_proposal": 2, "steps": [11, 12], "what": "Extracting Orders before Payments and extracting Pricing late without a golden master.", "why": "Rejected because Orders depends on Payments, and Pricing requires strict characterization testing."}, {"from_proposal": 3, "steps": [], "what": "Compressing the plan into 10 steps.", "why": "Rejected because 10 steps lack the operational granularity needed for rollback procedures and peak season protection."}]}, {"proposal": 2, "assessment": "improved", "what_changed": "This proposal transformed from a generic template into a highly rigorous, constraint-driven execution plan. It explicitly tackled the hardest constraints by introducing a scope ladder, a rollback charter, and a four-stage cutover playbook. It correctly abandoned the unrealistic goal of blanket test coverage in favor of seam-level verification.", "improvements": ["Introduced a strict peak-aware calendar, scope ladder, and rollback charter to enforce constraints.", "Replaced blanket test coverage with seam-level verification using golden masters and shadow diffing.", "Defined a reusable four-stage cutover playbook with reverse CDC for genuine reversibility.", "Added executable architecture enforcement using ArchUnit and SQL linters to prevent re-coupling."], "regressions": ["The 18 steps are dense and might be overwhelming for a quick read.", "Team reorganization is implied but less explicitly detailed as a standalone step compared to Proposal 1."], "taken": [{"from_proposal": 1, "steps": [4, 8, 21], "what": "Peak-season protection framework, shadow traffic with checksum comparison, and keeping read-only access post-cutover.", "why": "Adopted to ensure peak seasons are protected and to provide cheap insurance via legacy fallback."}, {"from_proposal": 3, "steps": [3, 4, 7], "what": "CDC via Debezium with transactional outbox, golden master for pricing, and real-time catalogue indexing.", "why": "Adopted as the foundational data strategy and the only defensible way to move the complex pricing module."}], "rejected": [{"from_proposal": 1, "steps": [8, 15, 21], "what": "Raising test coverage to 70%, refactoring pricing rules into a DSL, and decommissioning the legacy database early.", "why": "Rejected because 70% coverage is unachievable, DSL refactoring is high-risk scope creep, and early decommissioning destroys the rollback target."}, {"from_proposal": 3, "steps": [4, 7, 9], "what": "Moving pricing to a new project while reading a replica, placing checkout before payment, and lacking a month-by-month calendar.", "why": "Rejected because reading a replica keeps the database coupled, checkout needs payment first, and the calendar is the binding constraint."}]}, {"proposal": 3, "assessment": "improved", "what_changed": "The proposal expanded to 12 steps, adding crucial operational layers like strategic freeze planning and core infrastructure setup. It successfully integrated the black-box pricing strategy and CDC patterns, making it much more realistic than its previous version. However, it still lacks the deep data-cutover mechanics and strict calendar enforcement seen in Proposal 2.", "improvements": ["Added explicit mobilization and strategic freeze planning to protect January and July peaks.", "Introduced the Golden Master characterization test harness and replay engine.", "Detailed the Anti-Corruption layer with CDC and Outbox patterns to decouple the database."], "regressions": ["Still omits a detailed, reusable data cutover playbook like the one in Proposal 2.", "The Anti-Corruption Layer step mixes CDC and read-only replicas in a way that does not clearly resolve the shared database problem."], "taken": [{"from_proposal": 1, "steps": [1, 14], "what": "Explicit peak-season window planning and extracting pricing as-is.", "why": "Adopted to ensure changes avoid freeze periods and to mitigate the massive risk of rewriting the pricing engine."}, {"from_proposal": 2, "steps": [3, 13], "what": "Strangler Fig Facade at the API gateway and stored procedure refactoring.", "why": "Adopted to establish a central traffic control point and handle complex legacy database logic."}], "rejected": [{"from_proposal": 1, "steps": [9, 15], "what": "Extracting Search after building the pipeline, and refactoring pricing rules in Phase 2.", "why": "Rejected because the pipeline must be built before extraction, and pricing refactoring adds unnecessary risk."}, {"from_proposal": 2, "steps": [7, 12], "what": "Extracting Inventory as the seventh step and Pricing after Order Management.", "why": "Rejected because Inventory is a critical dependency for Checkout and must be extracted immediately before it."}]}]}
[ROUND 2]
{"round_summary": "The agents converged on a **calendar-first approach** with explicit peak-season freezes and seam-level verification. They abandoned unrealistic blanket test coverage goals in favor of golden-master characterization and four-stage cutover playbooks.", "converging": true, "proposals": [{"proposal": 1, "assessment": "improved", "what_changed": "It abandoned its unrealistic **70% monolith coverage goal**. It adopted the calendar-first, scope-ladder, and four-stage cutover playbook from Proposal 2. It also parallelized the pricing rules cataloging to avoid false dependencies.", "improvements": ["Abandoned blanket 70% coverage in favor of seam-level golden master verification.", "Adopted explicit freeze windows and a scope ladder to protect peak seasons.", "Parallelized pricing characterization with data platform work to shorten the critical path."], "regressions": ["The 20-step sequence remains highly granular, risking rigid execution over adaptive delivery.", "Some steps still imply sequential dependencies that could be parallelized further."], "taken": [{"from_proposal": 2, "steps": [1, 2, 3, 4, 6, 7], "what": "Calendar-first charter, scope ladder, table ownership enforcement, seam-level verification, and the four-stage cutover playbook.", "why": "Used to structure the entire program around peak-season constraints and reversible data migrations."}, {"from_proposal": 3, "steps": [4], "what": "The replay engine concept for the golden master.", "why": "Used to simplify the characterization harness by recording and diffing real production requests."}], "rejected": [{"from_proposal": 3, "steps": [10], "what": "Implementing the checkout orchestrator before the payment service.", "why": "Rejected because checkout orchestration requires a stable payment boundary to avoid calling back into the monolith."}]}, {"proposal": 2, "assessment": "improved", "what_changed": "It refined its strong foundation by explicitly **deferring the checkout saga orchestration** until after the first peak. It also clarified the mobile app versioning and authentication strategies to prevent customer disruption.", "improvements": ["Deferred the distributed checkout saga to a post-peak decision, keeping the transaction in the monolith during peaks.", "Added explicit abort criteria and a migration enablement squad to manage shared risks.", "Clarified that pricing dependencies are inverted via event-fed read models rather than synchronous fan-out."], "regressions": ["Deferring the checkout saga means the monolith remains a critical bottleneck for the core transaction throughout the year.", "The 18-step plan is dense and requires high discipline to execute without burning out the enablement squad."], "taken": [{"from_proposal": 1, "steps": [4], "what": "The explicit 6-week peak-season freeze framework with rehearsed rollback.", "why": "Used to harden the calendar constraints and ensure no risky changes happen near the sales peaks."}, {"from_proposal": 3, "steps": [9], "what": "Per-country ramps for the pricing cutover.", "why": "Used to mitigate jurisdictional financial and legal exposure during the pricing migration."}], "rejected": [{"from_proposal": 3, "steps": [11], "what": "Implementing the checkout saga within the 12-month migration window.", "why": "Rejected the implementation to protect the peak season, opting to keep the transaction in the monolith until after the first peak."}]}, {"proposal": 3, "assessment": "mixed", "what_changed": "It adopted the **golden master and CDC strategies** from the other proposals, improving its data and testing rigor. However, it still lacks the operational depth of the four-stage cutover playbook and explicit rollback rehearsals.", "improvements": ["Adopted the Golden Master replay engine for pricing and critical paths.", "Moved Inventory extraction earlier to unblock real-time stock visibility.", "Extracted a dedicated Payment service to isolate PCI scope from the Checkout orchestrator."], "regressions": ["The four-stage cutover playbook is glossed over, leaving data migration risks under-specified.", "Lacks explicit rollback game-day rehearsals and automated rollback controllers."], "taken": [{"from_proposal": 2, "steps": [6, 7], "what": "Seam-level verification and data platform enforcement.", "why": "Used to replace naive test coverage goals with boundary verification and strict table ownership."}, {"from_proposal": 1, "steps": [5], "what": "Black-box extraction for the pricing module.", "why": "Used to avoid refactoring the 200k LOC rules engine during the high-pressure migration window."}], "rejected": [{"from_proposal": 2, "steps": [16], "what": "Deferring the checkout saga orchestration to a post-peak decision.", "why": "Rejected the deferral, insisting on implementing the saga within the 12-month window, which increases peak-season risk."}]}]}
[FINAL]
{"summary": "The final round presents highly mature, constraint-driven migration plans that correctly prioritize peak-season safety and data decoupling over naive service extraction. The proposals converge on a calendar-first approach, golden-master characterization for the pricing module, and a four-stage cutover playbook, demonstrating strong learning from prior rounds.", "assessments": [{"proposal": 1, "fitness": "strong", "strengths": ["Explicit four-stage cutover playbook (Shadow, Read, Write, Delete) with reverse CDC for safe rollbacks.", "Parallelizes the pricing rules catalog (Step 5) with data platform work, removing false dependencies.", "Strong emphasis on automated rollback controllers and error budgets tied to business SLOs."], "weaknesses": ["Attempting to extract the Checkout Saga (Step 16) within the 12-month window introduces unnecessary risk close to the second peak, rather than deferring the extraction entirely.", "The 20-step sequence is highly detailed but risks becoming a rigid critical path if early steps slip."]}, {"proposal": 2, "fitness": "strong", "strengths": ["Step 5 (Split the deployment unit) achieves independent deployability immediately by separating builds before fully decoupling code, retiring the maintenance window early.", "Step 16 explicitly defers the full Checkout Saga extraction to after the first peak (or to a follow-up program), keeping a thin orchestrator in the monolith to guarantee peak safety.", "Rigorous enforcement of table ownership via database roles and CI linters, preventing silent re-coupling."], "weaknesses": ["Deferring the Checkout Saga extraction might leave the monolith's checkout path as a bottleneck for longer, requiring careful capacity planning for the orchestrator.", "The 18-step plan is dense and assumes a highly disciplined enablement squad to drive the parallel data platform work."]}, {"proposal": 3, "fitness": "weak", "strengths": ["Good high-level structure and clear identification of the Golden Master and CDC patterns.", "Correctly identifies the need to extract Inventory early to resolve the 15-minute warehouse sync bottleneck."], "weaknesses": ["Flawed sequencing: Step 11 extracts Checkout Orchestration before Step 12 extracts the Payment Service, making the Saga implementation impossible or highly coupled.", "Lacks the operational depth of the four-stage cutover playbook and explicit rollback rehearsals seen in the other proposals.", "Compresses a 12-month, two-peak program into 16 steps without month-by-month calendar enforcement in the execution steps."]}], "ranking": [2, 1, 3], "ranking_reasons": "Proposal 2 is ranked first because it brilliantly separates deployment independence (Step 5) from logical service extraction, and takes the safest possible stance on the Checkout Saga by deferring its extraction to protect the peaks. Proposal 1 is a close second, offering exceptional detail on the four-stage cutover and parallel pricing work, but it risks the second peak by extracting the Checkout Saga in Step 16. Proposal 3 is ranked last due to a critical sequencing error (Checkout before Payment) and a lack of operational rigor around data cutover and rollbacks.", "versus_initial": [{"proposal": 1, "verdict": "better", "why": "The initial Proposal 1 aimed for an unrealistic 70% monolith test coverage and serialized the entire migration into 24 steps, ignoring the hard constraints of the peak seasons.", "how": "The final Proposal 2 (my first choice) abandons blanket coverage for seam-level golden-master verification, parallelizes the data platform work, and explicitly builds the calendar and freeze windows into the foundational steps."}, {"proposal": 2, "verdict": "better", "why": "The initial Proposal 2 had a strong platform foundation but fatally delayed team reorganization and lacked a concrete data migration strategy for the 1.2TB database.", "how": "The final Proposal 2 introduces the four-stage cutover playbook with reverse CDC, enforces table ownership at the database engine level, and explicitly schedules team transition alongside the scope ladder."}, {"proposal": 3, "verdict": "better", "why": "The initial Proposal 3 handled the pricing module pragmatically but lacked granular database details and compressed the timeline unrealistically.", "how": "The final Proposal 2 expands the data strategy into a dedicated track (Step 7) with explicit join elimination and outbox patterns, and rigorously maps the 12-month timeline against the immovable January and July peaks."}], "improved_over_initial": true, "improvement_summary": "The deliberation process successfully stripped away unrealistic goals (like 70% monolith coverage) and replaced them with pragmatic, constraint-driven mechanisms (golden master, four-stage cutover, calendar-first freezes). The agents learned to treat data decoupling and peak-season protection as the primary drivers of the sequence, rather than afterthoughts.", "process_evaluation": "The convergence was largely earned through rigorous critique in previous rounds, particularly the rejection of blanket test coverage in favor of seam-level verification. The agents successfully adopted each other's best ideas (e.g., Proposal 2's calendar and playbook, Proposal 1's parallel pricing work). However, Proposal 3 failed to fully internalize the dependency graph, resulting in a flawed sequence in the final round. The strong convergence between Proposals 1 and 2 shows effective synthesis, though they became somewhat structurally identical, differing mainly in the treatment of the Checkout Saga and early deployment splitting.", "process_issues": ["Proposal 3 introduced a critical dependency violation in the final round (extracting Checkout before Payment), indicating a lack of deep architectural validation during the refinement phase.", "Proposals 1 and 2 converged so closely on the 'four-stage playbook' and 'scope ladder' that they essentially mirrored each other's structure, risking a lack of divergent alternative approaches in the final round.", "The agents did not sufficiently challenge the premise of extracting all 8 services within 12 months; a more radical approach might have been to defer 2-3 services to a year-2 program entirely."], "suggestions": ["Introduce a 'Devil's Advocate' agent in the final round to explicitly challenge the 12-month timeline and propose an 18-month scope, ensuring the plans aren't just optimizing a potentially impossible constraint.", "Require agents to explicitly map their steps to a month-by-month calendar in the final output to prove the 12-month feasibility, rather than just stating 'calendar-first'.", "Enforce a dependency-check step where agents must validate their extraction sequence against a strict topological sort of the domain boundaries before finalizing the plan."]}
[VOTE COMPARISON]
{"agrees": false, "comment": "I disagree with the selection of Proposal 1 because it prioritizes architectural completeness over **pragmatic risk management**. The voters heavily rewarded the explicit metrics of Proposal 1, while I prioritized the realistic protection of the critical sales peaks.\n\nThe voters' justifications reveal a clear **bias towards structural detail** over operational safety. They penalized Proposal 2 for deferring the checkout extraction, failing to realize that finishing the migration is secondary to surviving the peak seasons."}The final round, ranked blind
Why this order
Proposal 2 is ranked first because it brilliantly separates deployment independence (Step 5) from logical service extraction, and takes the safest possible stance on the Checkout Saga by deferring its extraction to protect the peaks. Proposal 1 is a close second, offering exceptional detail on the four-stage cutover and parallel pricing work, but it risks the second peak by extracting the Checkout Saga in Step 16. Proposal 3 is ranked last due to a critical sequencing error (Checkout before Payment) and a lack of operational rigor around data cutover and rollbacks.
The ranking
- Proposal 2 strong Strengths
- Step 5 (Split the deployment unit) achieves independent deployability immediately by separating builds before fully decoupling code, retiring the maintenance window early.
- Step 16 explicitly defers the full Checkout Saga extraction to after the first peak (or to a follow-up program), keeping a thin orchestrator in the monolith to guarantee peak safety.
- Rigorous enforcement of table ownership via database roles and CI linters, preventing silent re-coupling.
Weaknesses- Deferring the Checkout Saga extraction might leave the monolith's checkout path as a bottleneck for longer, requiring careful capacity planning for the orchestrator.
- The 18-step plan is dense and assumes a highly disciplined enablement squad to drive the parallel data platform work.
- Proposal 1 strong selected by the vote Strengths
- Explicit four-stage cutover playbook (Shadow, Read, Write, Delete) with reverse CDC for safe rollbacks.
- Parallelizes the pricing rules catalog (Step 5) with data platform work, removing false dependencies.
- Strong emphasis on automated rollback controllers and error budgets tied to business SLOs.
Weaknesses- Attempting to extract the Checkout Saga (Step 16) within the 12-month window introduces unnecessary risk close to the second peak, rather than deferring the extraction entirely.
- The 20-step sequence is highly detailed but risks becoming a rigid critical path if early steps slip.
- Proposal 3 weak Strengths
- Good high-level structure and clear identification of the Golden Master and CDC patterns.
- Correctly identifies the need to extract Inventory early to resolve the 15-minute warehouse sync bottleneck.
Weaknesses- Flawed sequencing: Step 11 extracts Checkout Orchestration before Step 12 extracts the Payment Service, making the Saga implementation impossible or highly coupled.
- Lacks the operational depth of the four-stage cutover playbook and explicit rollback rehearsals seen in the other proposals.
- Compresses a 12-month, two-peak program into 16 steps without month-by-month calendar enforcement in the execution steps.
The vote, confronted with the analyst
the analyst disagrees with the vote
I disagree with the selection of Proposal 1 because it prioritizes architectural completeness over pragmatic risk management. The voters heavily rewarded the explicit metrics of Proposal 1, while I prioritized the realistic protection of the critical sales peaks.
The voters' justifications reveal a clear bias towards structural detail over operational safety. They penalized Proposal 2 for deferring the checkout extraction, failing to realize that finishing the migration is secondary to surviving the peak seasons.
Is the analyst's first choice better than the initial proposals? better than every initial proposal
The deliberation process successfully stripped away unrealistic goals (like 70% monolith coverage) and replaced them with pragmatic, constraint-driven mechanisms (golden master, four-stage cutover, calendar-first freezes). The agents learned to treat data decoupling and peak-season protection as the primary drivers of the sequence, rather than afterthoughts.
| Initial proposal | Verdict | Why | How |
|---|---|---|---|
| Proposal 1 |
better | The initial Proposal 1 aimed for an unrealistic 70% monolith test coverage and serialized the entire migration into 24 steps, ignoring the hard constraints of the peak seasons. |
The final Proposal 2 (my first choice) abandons blanket coverage for seam-level golden-master verification, parallelizes the data platform work, and explicitly builds the calendar and freeze windows into the foundational steps. |
| Proposal 2 |
better | The initial Proposal 2 had a strong platform foundation but fatally delayed team reorganization and lacked a concrete data migration strategy for the 1.2TB database. |
The final Proposal 2 introduces the four-stage cutover playbook with reverse CDC, enforces table ownership at the database engine level, and explicitly schedules team transition alongside the scope ladder. |
| Proposal 3 |
better | The initial Proposal 3 handled the pricing module pragmatically but lacked granular database details and compressed the timeline unrealistically. |
The final Proposal 2 expands the data strategy into a dedicated track (Step 7) with explicit join elimination and outbox patterns, and rigorously maps the 12-month timeline against the immovable January and July peaks. |
Evaluation of the process
The convergence was largely earned through rigorous critique in previous rounds, particularly the rejection of blanket test coverage in favor of seam-level verification. The agents successfully adopted each other's best ideas (e.g., Proposal 2's calendar and playbook, Proposal 1's parallel pricing work). However, Proposal 3 failed to fully internalize the dependency graph, resulting in a flawed sequence in the final round.
The strong convergence between Proposals 1 and 2 shows effective synthesis, though they became somewhat structurally identical, differing mainly in the treatment of the Checkout Saga and early deployment splitting.
- Proposal 3 introduced a critical dependency violation in the final round (extracting Checkout before Payment), indicating a lack of deep architectural validation during the refinement phase.
- Proposals 1 and 2 converged so closely on the 'four-stage playbook' and 'scope ladder' that they essentially mirrored each other's structure, risking a lack of divergent alternative approaches in the final round.
- The agents did not sufficiently challenge the premise of extracting all 8 services within 12 months; a more radical approach might have been to defer 2-3 services to a year-2 program entirely.
- Introduce a 'Devil's Advocate' agent in the final round to explicitly challenge the 12-month timeline and propose an 18-month scope, ensuring the plans aren't just optimizing a potentially impossible constraint.
- Require agents to explicitly map their steps to a month-by-month calendar in the final output to prove the 12-month feasibility, rather than just stating 'calendar-first'.
- Enforce a dependency-check step where agents must validate their extraction sequence against a strict topological sort of the domain boundaries before finalizing the plan.
Convergence: steps changed per round
- claudeHaiku4.5_refine_1 claudeHaiku4.5 · anthropic/claude-haiku-4-5
- deepseek-flash_refine_2 deepseek-flash · deepseek/deepseek-flash
- qwen3.8-flash_refine_3 qwen3.8-flash · alibaba/qwen3.8-flash
- mean of the agents
| Steps kept, added and removed | Round 1 | Round 2 |
|---|---|---|
| claudeHaiku4.5_refine_1 |
5 | 5 |
| deepseek-flash_refine_2 |
4 | 15 |
| qwen3.8-flash_refine_3 |
2 | 4 |
Contributions of each agent
- claudeHaiku4.5_refine_1 claudeHaiku4.5 · anthropic/claude-haiku-4-5 · extended thinking, 15.0k tokens · temp 1
- deepseek-flash_refine_2 deepseek-flash · deepseek/deepseek-flash · thinking on, effort low
- qwen3.8-flash_refine_3 qwen3.8-flash · alibaba/qwen3.8-flash · thinking on, budget 4.0k tokens
| Agent | Steps of the selected plan it introduced | Steps introduced | Copied by others | Survived to the final round | Ideas taken from it | Ideas rejected | Declared adopted | Declared rejected | Votes received |
|---|---|---|---|---|---|---|---|---|---|
| claudeHaiku4.5_refine_1 selected plan |
12 | 44 | 5 | 16 | 4 | 2 | 2 | ||
| deepseek-flash_refine_2 |
7 | 32 | 11 | 19 | 4 | 3 | 1 | ||
| qwen3.8-flash_refine_3 |
1 | 23 | 2 | 9 | 4 | 4 | 0 |
Efficiency of each agent
Cost per step
Steps per minute of model time
Timeline
Costs
Two separate things were paid for in this run:
- The planning process itself ("Deliberation" below): the 12 LLM calls that produced the plan — 3 agents drafting and refining over 3 rounds, then 3 voters. This is the cost of obtaining the plan. Running
slow-thinkercosts exactly this. - The optional evaluation ("Analysis" below, on yellow like everything the analysis adds): the 5 calls made afterwards by
slow-thinker-report --analyzeso that a reviewing model explains how the proposals evolved and judges the outcome. It does not change the plan and is only paid if you ask for it.
0.30
0.086
0.39
Deliberation (the planning process), by model
| Model | Thinking | Calls | Input tokens | Output tokens | Reasoning | Model time | Cost |
|---|---|---|---|---|---|---|---|
| claudeHaiku4.5 · anthropic/claude-haiku-4-5 | extended thinking, 15.0k tokens · temp 1 | 4 | 51.7k | 40.3k | 12.3k | 8 min 1 s | 0.25 |
| deepseek-flash · deepseek/deepseek-flash | thinking on, effort low | 4 | 45.7k | 47.7k | 31.7k | 3 min 29 s | 0.035 |
| qwen3.8-flash · alibaba/qwen3.8-flash | thinking on, budget 4.0k tokens | 4 | 47.1k | 18.5k | 9.8k | 5 min 7 s | 0.016 |
| Total | 12 | 144.5k | 106.6k | 53.8k | 16 min 37 s | 0.30 |
Deliberation (the planning process), by call
| Phase | Call | Model | Input tokens | Output tokens | Reasoning | Time | Cost |
|---|---|---|---|---|---|---|---|
| Round 0 | claudeHaiku4.5_initial_1 | claudeHaiku4.5 · anthropic/claude-haiku-4-5 | 1.3k | 8.8k | 4.6k | 1 min 23 s | 0.045 |
| Round 0 | deepseek-flash_initial_2 | deepseek-flash · deepseek/deepseek-flash | 1.0k | 10.5k | 7.9k | 46 s | 0.006 |
| Round 0 | qwen3.8-flash_initial_3 | qwen3.8-flash · alibaba/qwen3.8-flash | 995 | 4.6k | 1.7k | 1 min 18 s | 0.002 |
| Round 1 | claudeHaiku4.5_refine_1 | claudeHaiku4.5 · anthropic/claude-haiku-4-5 | 10.9k | 8.9k | 2.0k | 1 min 53 s | 0.055 |
| Round 1 | deepseek-flash_refine_2 | deepseek-flash · deepseek/deepseek-flash | 9.6k | 18.2k | 11.5k | 1 min 26 s | 0.012 |
| Round 1 | qwen3.8-flash_refine_3 | qwen3.8-flash · alibaba/qwen3.8-flash | 9.9k | 5.2k | 2.0k | 1 min 30 s | 0.004 |
| Round 2 | claudeHaiku4.5_refine_1 | claudeHaiku4.5 · anthropic/claude-haiku-4-5 | 18.7k | 19.5k | 2.9k | 3 min 58 s | 0.12 |
| Round 2 | deepseek-flash_refine_2 | deepseek-flash · deepseek/deepseek-flash | 16.7k | 17.9k | 11.3k | 1 min 10 s | 0.013 |
| Round 2 | qwen3.8-flash_refine_3 | qwen3.8-flash · alibaba/qwen3.8-flash | 17.1k | 6.5k | 4.0k | 1 min 47 s | 0.006 |
| Voting | claudeHaiku4.5_voter_1 | claudeHaiku4.5 · anthropic/claude-haiku-4-5 | 20.8k | 3.1k | 2.8k | 47 s | 0.036 |
| Voting | deepseek-flash_voter_2 | deepseek-flash · deepseek/deepseek-flash | 18.5k | 1.1k | 942 | 7 s | 0.003 |
| Voting | qwen3.8-flash_voter_3 | qwen3.8-flash · alibaba/qwen3.8-flash | 19.0k | 2.3k | 2.1k | 32 s | 0.004 |
Analysis (optional evaluation, not part of the process), by call
| Call | Model | Input tokens | Output tokens | Reasoning | Time | Cost |
|---|---|---|---|---|---|---|
| analysis of round 0 | alibaba/qwen3.7-plus | 9.2k | 6.6k | 6.0k | 1 min 46 s | 0.014 |
| analysis of round 1 | alibaba/qwen3.7-plus | 26.6k | 6.6k | 4.9k | 1 min 42 s | 0.021 |
| analysis of round 2 | alibaba/qwen3.7-plus | 41.2k | 6.2k | 4.9k | 1 min 14 s | 0.026 |
| analysis of final | alibaba/qwen3.7-plus | 33.8k | 4.2k | 2.6k | 52 s | 0.020 |
| analysis of vote comparison | alibaba/qwen3.7-plus | 1.5k | 2.2k | 2.1k | 40 s | 0.004 |
| Total | 112.3k | 25.7k | 20.5k | 6 min 15 s | 0.086 |