Platform Architecture Without Rework
Reduce avoidable platform rework with evidence-based boundaries, consumer-tested contracts, explicit team interactions, and recoverable migration steps.
trigger="A shared platform change repeatedly forces coordinated releases, duplicates business rules, or blocks a product capability." owner="The architecture owner accountable for the affected capability and its consumer contracts." participants={["Platform product owner", "Application owners", "Consumer representatives", "Data owner", "Security reviewer", "Operations lead"]} prerequisites={[ "A concrete change problem, its affected consumers, and evidence of coordination or operating cost.", "A map of business invariants, data readers and writers, dependencies, and ownership.", "Representative contract tests, a safe migration environment, and agreed recovery constraints." ]} outputs={[ "A boundary decision record with alternatives, assumptions, and consumer obligations.", "A versioned contract and a tested transition plan with writer authority by phase.", "A platform interaction agreement and an owned retirement register for temporary components." ]} doneWhen={[ "Representative consumers can complete their task through the proposed contract.", "The chosen boundary preserves business invariants and has an accountable operator.", "Compatibility, shadow safety, failure handling, and recovery gates pass.", "Temporary adapters, old contracts, and data copies have evidence-based retirement criteria." ]} />
Reduce avoidable rework, not all change
A platform cannot prevent changing requirements. It can make the cost of a change visible and keep one implementation decision from spreading unnecessarily through every consumer.
Start with an observed problem: a billing change requires several unrelated deployments, a shared library blocks urgent fixes, or teams repeat the same unsafe deployment setup. The output of this playbook is a tested boundary and transition plan. It is not a promise of a fixed reduction in rework, a faster migration, or a permanent architecture.
Keep platform migration execution separate from this decision. A useful boundary can remain inside one deployable application; a team boundary or data lifecycle alone does not require a network service.
1. Map change, data, and invariants
The architecture owner follows several recent changes through code, deployment, data, and support. Record where teams waited, why releases were coordinated, and which failures crossed proposed boundaries. Distinguish necessary business coordination from accidental implementation coupling.
The data owner lists tables or stores, authorized writers, indirect readers, jobs, exports, and integrations. Include reporting and repair tools that bypass the application API. Mark invariants that must hold together, such as an entitlement and the transaction that grants it.
| Question | Evidence to collect | Decision it informs | | --- | --- | --- | | What changes together? | Recent changes and consumer impact | Module and contract scope | | What must remain consistent? | Business invariant and transaction boundaries | State ownership and coordination | | What needs separate operation? | Load, release, isolation, recovery requirements | Whether a service boundary earns its cost | | Who can support the boundary? | Operational ownership and incident history | Viable responsibility assignment | | Which dependencies are temporary? | Adapter, duplicate store, old-version inventory | Transition and retirement work |
Do not use deployment counts or team size as an automatic architecture rule. A coordinated release may be a tolerable tradeoff. Separating it can add network failure, version skew, and reconciliation without resolving the underlying business dependency.
2. Compare the smallest viable boundaries
The application and platform owners compare concrete alternatives before selecting a service. Test the hardest invariant and the most demanding consumer, not only the simplest endpoint.
| Candidate | Useful when | Costs and gates | | --- | --- | --- | | Internal module | One runtime is acceptable and ownership can be enforced in code | Dependency rules, tests, and clear access to shared state | | Versioned library | Consumers need local reusable behavior | Upgrade ownership, compatibility, security patches, runtime support | | Network service | Independent operation or ownership has measurable value | Network failure, latency, authorization, deployment and data contracts | | Managed capability | A provider can meet the required contract | Limits, integration, data handling, support, and exit evidence | | Retained boundary with targeted repair | The current structure is adequate except for a specific defect | Demonstrate that the repair addresses the observed problem |
A bounded context describes a model and language boundary. It does not require a separate database server. Shared infrastructure can host distinct ownership boundaries if access and change rules enforce them. Conversely, separate databases do not make coupled behavior independent.
Record the rejected options and the evidence that would cause reconsideration. “We may scale later” needs a measurable trigger, a review owner, and the cost of deferring the decision.
3. Define the consumer contract before expanding implementation
The contract owner records inputs, outputs, authorization, errors, idempotency, ordering, consistency, deadlines, quotas, and support expectations. For a library, include supported runtimes and failure behavior. For an event, include schema evolution, replay, duplicate delivery, and semantic meaning.
An additive field can still break a strict consumer, generated client, signature, or size limit. Version numbers and an API schema do not prove behavioral compatibility. Run tests from registered consumers and maintain examples of business semantics.
"type": "svg-architecture", "title": "Keep consumer contracts separate from implementation changes", "nodes": [ ], "links": [ ], "caption": "The adapter is optional transition machinery, not a second business-rule owner. Contract tests and state invariants govern whether an internal change is acceptable." }} />
The security reviewer tests object and tenant permissions at the boundary. A trusted internal network or caller-supplied identity field is not an authorization policy.
Gate: representative consumers pass contract tests, the operator accepts the service behavior, and the data owner accepts the invariant model. Unresolved semantics stay in the decision record rather than becoming undocumented implementation choices.
4. Plan API and library lifecycle explicitly
Use a versioning mechanism that consumers and infrastructure can operate. Path, header, or media-type strategies each require routing, cache, documentation, and observability support. See the API versioning guide for the wider execution sequence.
RFC 9745 defines Deprecation as a structured date, represented by an at-sign followed by Unix seconds. It signals deprecation, not immediate unavailability. RFC 8594 defines Sunset as an HTTP date for expected unavailability.
This illustrative header pair announces deprecation on January 1, 2027 and expected unavailability on July 1, 2027. These are example dates, not a recommended notice period:
Deprecation: @1798761600
Sunset: Thu, 01 Jul 2027 00:00:00 GMTTest the header values through the actual proxy and SDK path. Ensure the sunset date is not earlier than the deprecation date. Link consumers to an authenticated migration guide and communicate directly where headers will not reach decision-makers.
Set notice and support windows from contracts, risk, consumer release cycles, and operational capacity. Record an exception or an approved termination decision for consumers that cannot migrate. Neither “keep forever” nor “delete after a fixed number of days” is a sufficient policy.
For libraries, publish compatibility and support rules, pin resolved production dependencies, and test upgrades. Semantic versioning communicates intent; it does not catch accidental behavior changes. Security fixes may require a supported backport or an expedited consumer upgrade.
5. Match team interactions to the service offered
The platform product owner defines its users and the work the platform helps them finish. A team named after a technical layer is not automatically aligned to a business value stream.
Team Topologies distinguishes stream-aligned, enabling, complicated-subsystem, and platform teams. Its interaction modes include bounded collaboration, service consumption, and temporary help. Apply those distinctions to actual responsibilities:
| Team role | Example responsibility | Interaction to agree | | --- | --- | --- | | Stream-aligned | Own the customer onboarding outcome across its required systems | Consume supported platform capabilities; collaborate on unmet needs | | Platform | Offer a supported deployment capability as an internal product | Documented self-service, support, and change policy | | Enabling | Help a team learn a missing testing or reliability practice | Time-bounded assistance with a clear exit | | Complicated subsystem | Own a capability requiring specialist expertise | An explicit interface and specialist support boundary |
Measure whether a consumer can complete the intended task, where support is needed, and what failure recovery requires. A first-week deployment target or fixed autonomy percentage is not evidence that a platform serves its users.
Agree who owns an incident spanning product and platform. Publish a supported path, an exception process, and the consequence of using an unsupported dependency.
6. Prove the transition before moving authority
The migration owner chooses a slice with enough value to test the boundary and enough containment to recover. A strangler-style facade can support gradual replacement when interception is feasible, but adds its own availability and routing risks. The Microsoft pattern guidance includes these applicability constraints.
For shadow comparison, use read-only calls or an isolated target with production write credentials removed and outbound effects blocked. Sending duplicate requests asynchronously does not prevent duplicate payments, messages, jobs, or database changes. Compare semantic outcomes at a defined data version; protect sampled data and discrepancy records.
The data owner selects snapshot, change capture, outbox, or another supported propagation method. Record ordering, deletes, retries, reconciliation, and the authoritative writer in each phase. Do not improvise unrelated writes to two databases and assume both succeeded.
"type": "flow", "title": "Prove a boundary before transferring write authority", "steps": [ ], "caption": "Routing can change before data ownership in some designs. A rollback is safe only while the old implementation can read and preserve the authoritative state." }} />
7. Separate reversible releases from irreversible gates
Before new writes, returning traffic to the old implementation may be viable after routing and capacity checks. After new writes, the old store can be stale. Returning to it requires tested reverse propagation or reconciliation, compatible semantics, and fencing of the current writer.
Expand-contract changes preserve a compatibility window only while old and new readers and writers remain supported. Dropping a column or accepting a new state the old application cannot interpret closes that window. Require explicit approval before the destructive contract step.
| Failure | Owner and containment | Evidence before resuming | | --- | --- | --- | | Consumer behavior changes | Contract owner stops rollout or restores the adapter | Consumer and semantic regression tests | | Shadow produces a real effect | Migration owner disables shadow traffic | Credential, network, queue, and side-effect isolation tests | | Stores diverge | Data owner pauses authority transfer | Watermark, discrepancy classification, and repair results | | New writes cannot be represented by old code | Incident owner uses forward recovery or approved repair | Compatible target and reconciled affected records | | Platform support demand exceeds capacity | Platform owner limits onboarding or changes support scope | Supported operating load and explicit consumer expectations |
Do not label a migration reversible because it has a feature flag. Keep the exact conditions and last verified recovery point in the runbook.
8. Retire temporary components through evidence
The owner of each adapter, duplicate index, flag, old API, and data copy records its purpose, consumers, operating cost, exit criteria, and review trigger. Choose the observation period from business cycles, offline clients, scheduled jobs, and contractual obligations.
Check runtime usage alongside source references, job schedules, exports, and consumer acknowledgment. Zero observed requests in a short window is not proof of no remaining dependency. Verify restoration requirements and data retention before decommissioning old state.
Remove credentials and routing access in a controlled step before destructive removal where practical. Re-run contract, security, and recovery tests afterward. Close the migration only when responsibility has transferred and temporary components no longer hide unowned work.
9. Use a boundary decision record
Capability, observed problem, and accountable owner:
Consumers, value stream, and operational responsibilities:
Business invariants and current readers/writers:
Options compared and rejected, with evidence:
Selected boundary and contract version:
Permissions, consistency, deadlines, and failure semantics:
Consumer tests and platform interaction agreement:
Shadow isolation and data synchronization method:
Writer authority, cutover checkpoints, and recovery window:
Irreversible gates and authorized decision-maker:
Temporary components, retirement evidence, and owners:
Accepted limitations and reconsideration trigger:"The boundary addresses an observed change or operating problem.", "A module or targeted repair was compared with a network service.", "Consumers and owners have agreed the behavioral contract.", "Platform and enabling responsibilities are not conflated.", "Deprecation syntax, dates, delivery, and consumer support have been tested.", "Shadow traffic cannot make live external or data changes.", "New-write recovery and destructive schema gates are explicit.", "Temporary components have owners and verifiable retirement criteria." ]} />
10. Run a boundary change tabletop before implementation
Use one representative change request that crosses the proposed boundary. Include an ordinary feature, an authorization rule, a data correction and an incident scenario. Ask the responsible teams to trace each request from decision through deployment, operation and recovery using only the proposed contracts and ownership model.
For the feature, identify which team can approve the behavior, which contract changes, how consumers learn about it, and whether the release can remain independent. For authorization, identify the trusted identity, resource owner and denial evidence. For data correction, establish the authoritative writer, affected derived copies and reconciliation method. For the incident, name the coordinator, containment authority and recovery limit after new writes.
Record every point where participants need informal knowledge, shared database access, an undocumented approval or a coordinated release. Classify the dependency as intentional, temporary or a boundary defect. An intentional dependency needs an explicit operating contract. A temporary dependency needs an owner and retirement condition. A boundary defect requires revising the design before authority moves.
The tabletop should also test absence. What happens when the proposed platform, service owner, identity provider or delivery system is unavailable? A clean diagram often assumes every control plane is healthy. The operating model must define which actions stop, which degrade safely and which emergency route remains authorized.
Do not score the exercise by the number of services or teams involved. Score it by whether decisions, data authority, failure ownership and recovery evidence remain unambiguous. A modular monolith may pass this test more cleanly than an extracted service, which is a valid outcome.
11. Accept the architecture through observed change
After a bounded pilot, compare the original constraint with actual operation. Measure the same change type, workload and definitions used in the baseline. Record lead time components, coordination events, rework, incident behavior, support effort and operating cost. A faster release with more unresolved recovery risk is not a complete improvement.
Ask consumers whether they can discover the contract, test against a supported version, diagnose an error and request an exception without private escalation. Ask operators whether they can identify current authority, stop a rollout, restore a compatible state and reconcile affected records. Ask the data owner whether the new boundary preserves invariants under retry, delay and partial failure.
The acceptance decision can retain the boundary, narrow it, revise the interaction model or return the capability to a module. Preserve negative findings. One failed hypothesis can prevent a costly organization-wide split.
When the boundary is accepted, set the next review trigger. Useful triggers include repeated cross-boundary transactions, growing support demand, a new consumer class, a change in data regulation, failure of the recovery rehearsal, or an upcoming destructive migration. A diagram should evolve when authority or behavior changes, not merely on a calendar.
Preserve the rejected options
Keep the evidence for alternatives that were not selected, including a targeted repair, modular boundary, managed capability or different ownership model. State why each option failed the current requirements and which changed assumption would make it worth reconsidering.
This record prevents the selected architecture from becoming folklore. A later team can distinguish a permanent constraint from a time-bound capacity or vendor limitation. It also reduces repeated debate when the same proposal returns with a different name.
Do not describe rejection as universal technical inferiority. The option may fit another workload with different invariants, consumers, operating capacity or recovery needs. Preserve the local decision boundary, accountable owner, next review date, and specific evidence that would justify formally reopening the recorded decision.
Limitations
A contract can still encode the wrong domain model, and a successful pilot can miss a rare workflow. Keep unresolved consumer and data risks visible. This playbook does not certify zero downtime, eliminate future rework, or replace a system-specific recovery rehearsal.
Domain owners must approve the final architecture and release evidence. Editorial completion is not factual certification or permission to move production traffic.