Blog · 2026-06-10 · ~11 min read
Cross-team decisions: when one team's ADR creates another team's constraint
A backend platform team spends two months evaluating event formats. They run the trade-offs — Avro vs. Protobuf vs. JSON Schema — in a dozen Claude sessions, write a thorough ADR, get it reviewed by their tech lead, and mark it Accepted. The decision is solid. What the ADR doesn't say is that the mobile team and the data team both consume these events. The mobile team builds their Kafka consumer in Swift against the JSON Schema contract. The data team builds their pipeline in Python against the same. Eighteen months later, the platform team wants to migrate to Protobuf for better schema evolution guarantees. This is a reasonable decision. But the mobile team owns a quarterly release cycle and needs six weeks of lead time. The data team has two engineers on a different sprint cadence. Neither team's constraint was written anywhere — not in their own ADRs, not in the platform team's ADR, not in any decision record anyone can find. The constraint existed from the moment the platform team made their original choice. Nobody documented it, because nobody thought of the original decision as cross-cutting. It was, from their perspective, an internal platform implementation detail.
TL;DR
The most expensive class of undocumented decision is the cross-cutting one — where one team's architecture choice silently creates obligations for a different team. API contract decisions, shared schema decisions, event format decisions each create durable constraints that persist for years, but they're often written as service-local ADRs without explicit downstream stakeholder tracking. A cross-team ADR differs from a service-local ADR in three required fields: downstream stakeholders, notification record, and migration obligation. The governance ceremony that prevents constraint collisions runs RFC → cross-team review → ADR, not ADR → notification. The WhyChose extractor recovers the AI chat deliberation behind these decisions — including the ones whose synchronous discussion happened in a Zoom call that wasn't recorded.
What makes a decision cross-cutting
Most architecture decisions stay inside the service boundary. The team chooses a background job library, picks a caching layer, decides how to structure the internal domain model. These decisions may be consequential, but they're reversible without coordinating across teams. If you swap the job library in six months, no other team needs to change their code.
A cross-cutting decision is different in kind, not just degree. The test is simple: if you change this decision later, who do you need to tell? If the answer is "another team whose engineers will need to update their code, change their deployment, or adjust their operational practices," the decision is cross-cutting. It doesn't matter whether the decision originated inside your service — what matters is whether the consequences extend beyond your service boundary.
Three categories reliably produce cross-cutting decisions:
- API contracts. REST shapes, GraphQL schema, gRPC interfaces. Any contract another team calls is a cross-cutting decision. The version strategy — how long v1 is maintained, what breaking vs. non-breaking means, what the deprecation window is — creates hard obligations for every downstream caller.
- Shared data schemas. Database tables accessed by more than one service. Event schemas in a shared Kafka topic. S3 file formats read by multiple consumers. Any schema another team reads or writes is a shared contract, regardless of whether it's documented as one.
- Event formats and message contracts. The most commonly underdocumented. An event emitted from one service into a shared bus is a public API, even when nobody called it that. The teams consuming those events have built against the current shape; changing it requires coordinating their release timelines.
There's a fourth, subtler category: decisions that create load-bearing assumptions elsewhere. If your service decides to guarantee idempotency on writes, and another team's retry logic silently depends on that guarantee, your idempotency decision is cross-cutting — even if the other team never formally requested it. When you're looking for cross-cutting decisions in AI chat history, watch for phrases like "other teams can rely on," "we'll guarantee," and "as long as X remains true downstream" — these are the implicit contract-making phrases the extractor's trade-off markers capture at high confidence.
Why service-local ADR format doesn't work for cross-team decisions
The standard Nygard ADR template — Title, Status, Context, Decision, Consequences — is purpose-built for service-local decisions. The Consequences section covers impact within the service: what becomes easier, what becomes harder, what technical debt is accepted. It doesn't have a field for "who outside this team is now obligated to do something."
This gap has a concrete effect. When a cross-cutting decision is written as a service-local ADR, it produces a record that's complete from the author's perspective but operationally useless for every downstream team. The backend team's ADR for the event format decision might be excellent — thorough options analysis, honest trade-offs, clear decision statement. But it doesn't tell the mobile team they're a stakeholder. It doesn't say when the mobile team was notified. It doesn't specify the migration window. The downstream team finds out about the change when the backend team asks them to update their consumer.
A cross-team ADR needs three additional fields that service-local ADRs don't require:
- Downstream stakeholders. The specific teams or systems whose code or operations are affected by this decision, listed explicitly. This makes the record discoverable from both sides: the backend team can find it when planning a change; the mobile team can find it when asking "what decision originally set this contract."
- Notification record. When each downstream team was informed, who acknowledged, and what they said. Timestamped. This is the auditable difference between "we mentioned it in the standup" and "we formally notified the team and got their confirmation." The notification record is what lets you say, eighteen months later, whether the mobile team had a chance to raise their release-cycle constraint before the decision was finalized.
- Migration obligation. The concrete version path, deprecation window, or handoff timeline that downstream teams must complete. Not a vague "coordinate with downstream teams" — a specific date or version by which migration is required. This is the downstream team's contract, written down where they can reference it.
None of these fields are standard in the ADR templates most teams use. The standard Markdown ADR template doesn't include them. Neither does MADR, arc42, or any of the common tool-specific variants. Adding them to cross-cutting ADRs is a team-level convention, not a tooling default.
The governance ceremony that prevents constraint collisions
The standard service-local ADR lifecycle is: propose → discuss within team → accept. This lifecycle doesn't work for cross-cutting decisions because the people who need to review it — downstream stakeholders — aren't part of the team doing the proposing.
The ceremony that actually prevents constraint collisions has the RFC step before the ADR. An RFC is a pre-decision proposal that explicitly asks for input from stakeholders before the decision is made. For cross-cutting decisions, the RFC is load-bearing: it's the mechanism that surfaces downstream constraints while there's still time to incorporate them.
The full cycle looks like this:
- RFC: The proposing team writes a draft proposal with the options they're considering and explicit questions for downstream teams. "We're considering migrating from JSON Schema to Protobuf for event formats. Mobile team: what's your client library situation and what lead time do you need for a migration? Data team: does your pipeline have format constraints?" The RFC circulates to all named downstream stakeholders with a two-week comment window.
- Cross-team review: Each downstream team nominates a reviewer — typically the tech lead or the engineer who owns the integration. Their review is a GitHub PR review comment on the RFC document, not a Slack reaction. This creates an auditable record of who reviewed, what they said, and whether they raised constraints. A downstream team that doesn't review within the window is recorded as non-blocking, which is different from never having been asked.
- ADR: After the RFC comment window closes and reviews are incorporated, the ADR is written. It references the RFC and includes the downstream stakeholders section, notification record, and migration obligation. The ADR is Proposed until each downstream team's tech lead leaves a review; it moves to Accepted when the last review is recorded. This is a higher bar than service-local ADR acceptance, which typically requires only the local tech lead's sign-off.
The RFC step is the one that matters most. Decisions that skip it and go straight to ADR → notification are the ones that surface surprise constraints six months later. "We'll notify affected teams after we decide" is not a governance ceremony — it's a decision made in isolation with downstream teams informed rather than consulted. The notification might be accurate and thorough; it still doesn't incorporate the mobile team's release-cycle constraint, because that constraint has to be raised before the decision is final, not after.
Teams that run this ceremony consistently report that the downstream review step finds real constraints roughly half the time — not edge cases, but constraints that would have caused coordination problems within two quarters. The investment is the two-week RFC window. The return is not having to renegotiate the decision after teams have already built against it.
The downstream notification gap
Even when teams write cross-team ADRs and run RFC ceremonies, there's a common failure mode: the notification lives in the ADR and in the downstream team's email, but not in the downstream team's own decision log. Six months later, an engineer on the mobile team is looking at their own ADR history and can't find the constraint. They know their consumer is built against a particular schema, but they don't know it's obligated to a migration timeline set by a different team's ADR.
The fix is a downstream acknowledgement record — a lightweight entry in the downstream team's decision log that says: "We received and reviewed ADR-0031 from the platform team (event format migration to Protobuf). Mobile team will complete migration by 2027-Q1 per the agreed timeline. Review on file at [link to review comment]." This is not an ADR in the service-local sense; it's a log entry that preserves the constraint for the downstream team's own history.
Without this, cross-team constraints live only in the originating team's ADR — which is the wrong place for the downstream team to find them. A new mobile engineer reviewing their team's decision log to understand what constraints they're operating under will find their own ADRs, but not the platform team's. The constraint is effectively invisible to them. This is the same failure mode as rejection decisions that never get written down — the information exists somewhere, but it's not findable from the perspective of the person who needs it.
What AI chat history reveals about cross-team decisions
Cross-team decisions tend to have unusually rich AI chat trails, for a structural reason: they require more deliberation. A service-local decision might get resolved in a single thirty-minute Claude session. A cross-team decision typically involves multiple sessions spread over days — the initial options analysis, the prep session before the RFC review meeting, the debrief after the cross-team review comes back with constraints, the final decision session after those constraints are incorporated.
The extractor captures all of these as separate records, each with the deliberation context from that moment. The pre-RFC prep session typically contains the strongest signal — this is where engineers work through the options in detail before presenting them to stakeholders. The post-review debrief contains the constraint-incorporation reasoning — "the mobile team said they need twelve weeks lead time, which changes our deployment plan to..." This is exactly the kind of reasoning that disappears when the decision is finalized and written up as a clean ADR without the back-and-forth.
When running the extractor on historical chat exports to recover cross-team decisions, look for a specific pattern: multiple extracted records that reference the same decision topic from different dates. A record from March that discusses the options, a record from April that incorporates a constraint, and a record from April that documents the final decision — together, these reconstruct the full deliberation arc for a cross-team decision that may have only a single-sentence ADR in the repository.
The trade-off marker pattern is particularly strong for cross-cutting decisions. Engineers tend to frame cross-team trade-offs explicitly: "the advantage is X for us, but the cost is Y for the mobile team." The extractor's trade-off markers assign high confidence to these records, and the downstream-team framing makes them identifiable as cross-cutting rather than service-local.
Recovering decisions from meetings that weren't recorded
The hardest cross-team decisions to recover are the ones where the deliberation happened synchronously — in a design review, an architecture review board meeting, or a cross-team planning call — and the meeting wasn't recorded. The decision might be in someone's notes, or it might have been summarized in a Slack thread that has since been archived. The original reasoning is often only recoverable through the AI chat sessions that happened around the meeting, not in it.
Two sessions are always worth extracting for this case: the session where the proposing engineer prepared for the review meeting, and the session where they processed the outcome afterward. Engineers who use AI as a thinking partner typically prep for architecture reviews by working through their own position — "the argument I'm going to make is X, the objections I expect are Y and Z" — and debrief afterward — "the mobile team raised a constraint I hadn't considered, which changes the timeline to..." Both sessions contain cross-team decision signal even though neither happened in the meeting itself.
On the downstream team's side, the same pattern holds. The tech lead who reviewed the RFC in a Zoom call likely debriefed with their own AI assistant: "we reviewed the platform team's event format proposal, and we need to push back on the timeline because our release cycle doesn't allow for less than twelve weeks." This debrief session contains the constraint articulation that should have been in the RFC review comment but may have only been spoken aloud in the call.
Recovery protocol for a specific cross-team decision: (1) identify the approximate date range from Jira epic history, PR timestamps, or Slack messages; (2) export ChatGPT history and Claude conversations from the proposing engineer and the downstream tech lead; (3) run the extractor on both exports; (4) cross-reference extracted records by date against the known decision timeline; (5) write the recovered reasoning into the ADR's Context section, noting that it was recovered from AI chat history rather than written contemporaneously.
The recovered record won't be as clean as a contemporaneous ADR. It will have gaps — the synchronous constraint negotiation that happened in the meeting itself, the informal hallway agreement about the migration window. But it will capture the reasoning that each engineer articulated before and after the meeting, which is often more honest and more complete than what ended up in the meeting notes, because AI chat is where engineers work through their actual position rather than the position they present in a group setting.
For teams where Slack contains decision-adjacent discussion, cross-team constraint threads are often accessible via the Slack export even when meeting recordings aren't available. The combination of Slack thread context and AI chat deliberation typically recovers enough signal to reconstruct the material terms of the decision.
A cross-team ADR template
Standard ADR templates omit the fields that cross-team decisions require. The following template extends the standard Markdown format with the three additional sections. All standard fields are retained for compatibility with existing ADR tooling:
# ADR-0042: Event format — migrate from JSON Schema to Protobuf
**Date:** 2026-03-15
**Status:** Accepted
**Deciders:** Platform team tech lead, mobile tech lead (reviewer), data tech lead (reviewer)
**RFC:** [RFC-0017](link-to-rfc-document) — open 2026-02-28 to 2026-03-14
## Context
The platform event bus currently uses JSON Schema for all emitted events. Two downstream teams (mobile, data) consume these events. We evaluated migration to Protobuf after encountering schema drift issues in Q4 2025, where two consumers built against undocumented optional fields.
Evaluated options: (1) JSON Schema with stricter governance, (2) Avro, (3) Protobuf 3.
## Decision
Migrate to Protobuf 3. Maintain JSON Schema contract through 2027-Q1 to allow downstream migration.
## Consequences
Schema evolution is now explicit and breaking changes require a version bump. Binary encoding reduces payload size ~40%. Downstream consumers must add a Protobuf dependency.
## Downstream stakeholders
- **Mobile team** — Swift Kafka consumer at `ios/Sources/EventConsumer/`. Lead: @mobiletech. Review: [link]. Constraint raised: minimum 12 weeks lead time for release inclusion.
- **Data team** — Python pipeline at `data/pipelines/platform_events/`. Lead: @datapipeline. Review: [link]. No constraint beyond the migration window.
## Notification record
| Team | Notified | Reviewer | Review date | Notes |
|---|---|---|---|---|
| Mobile | RFC circulated 2026-02-28 | @mobiletech | 2026-03-10 | 12-week minimum lead time |
| Data | RFC circulated 2026-02-28 | @datapipeline | 2026-03-12 | Approved, no constraint |
## Migration obligation
- JSON Schema v1 contract: maintained through **2026-Q4** (deadline: 2026-12-31)
- Protobuf v1 contract: available from **2026-04-01**
- Downstream migration window: **9 months** (2026-04-01 → 2026-12-31)
- Mobile team committed to migration by **2026-Q3** (2026-09-30)
- Data team committed to migration by **2026-Q2** (2026-06-30)
The notification record table is the most operationally important addition. Without it, "we notified downstream teams" is a claim; with it, it's an auditable fact. Eighteen months later, when the mobile team says they weren't aware of the migration timeline, the notification record either confirms or refutes the claim. This is the difference between a decision record and a decision record that can serve as the authoritative source of truth when stakeholders disagree about what was agreed.
The ADR governance pattern for larger organizations typically specifies who has authority to mark cross-team ADRs Accepted — usually the engineering manager or VP who owns the stakeholder relationships, not just the tech lead who owns the technical decision. This authority split matters: the technical decision can be made by engineers, but the migration obligation involves organizational commitments that may need manager-level sign-off.
Finding cross-team decisions in the quarterly triage pass
The quarterly decision review is the natural point for surface cross-cutting decisions that got written as service-local ADRs. During the triage pass, two questions identify misclassified service-local ADRs:
- "Are there other teams whose behavior would change if we revised this decision?" If yes, the record needs a downstream stakeholders section and a notification record, even retroactively.
- "If a new engineer on a different team read this record, would it tell them anything about obligations they might have?" If no, and the decision touches a shared contract, the record is incomplete.
Retroactive cross-team field addition is common and valuable. An ADR written eighteen months ago as service-local may have acquired downstream consumers since then — teams that built against the contract after it was published without the original team being aware. Identifying these retroactive dependencies and adding them to the ADR as a downstream stakeholders section with a note ("added in Q2 2026 retrospective — consumer added post-ADR acceptance") is better than leaving the dependency undocumented. The new engineer on the mobile team who is trying to understand what constraints their service operates under will thank you.
The quarterly triage also catches the inverse case: cross-team ADRs whose downstream obligations have been fulfilled and whose migration windows have closed. An ADR that tracked a multi-year schema migration, with all downstream teams confirmed migrated, can have its migration obligation field updated to "complete" and its Status updated to Accepted (migration closed). This keeps the decision log accurate without requiring deletion, which should almost never happen.
The compounding cost of undocumented cross-team constraints
Service-local undocumented decisions are expensive. Cross-team undocumented decisions are expensive squared. When a service-local decision goes undocumented, the cost is internal: a future engineer on the same team can't find the reasoning and has to reconstruct it. When a cross-team decision goes undocumented, the cost propagates: every engineer on every downstream team is operating against a constraint they can't find documentation for, and every cross-team coordination conversation about that area has to start by reconstructing the shared context that should have been written down once.
The downstream team's constraint reconstruction is the expensive part. When the platform team wants to revisit the event format decision, they pull up their ADR and have the full context. The mobile team pulls up their codebase and has to reconstruct: when was this contract established, who agreed to it, what was the reasoning, is there a migration plan, what's the timeline? If the mobile team used AI chat to process their side of the original decision, the extractor can recover their half of the deliberation. But recovering both halves requires both teams to run extractions, correlate the records by date, and reconstruct the shared context from two separate AI chat histories. This is recoverable — it's exactly what the extractor is built for — but it's significantly more expensive than writing the cross-team ADR correctly in the first place.
Teams that adopt the cross-team ADR format consistently report that the most valuable artifact is the notification record. The downstream stakeholders section tells you who is affected. The migration obligation tells you what they agreed to. But the notification record tells you whether they actually reviewed it and what they said — which is the only artifact that definitively answers "did this team know about this constraint before we made the decision that created it?"
Recover your cross-team decision history
Cross-team constraint decisions tend to have some of the richest AI chat deliberation trails — multiple sessions across multiple engineers, working through options and constraints from different perspectives. The WhyChose open-source extractor surfaces these records from your ChatGPT and Claude exports, including the constraint-incorporation sessions that happened between the RFC and the final ADR. Run it on both the proposing team's and the downstream team's exports to get the full deliberation arc.
Join the waitlist to process exports with the hosted service — cross-team linking (matching records from multiple export files to the same decision topic) is on the Pro roadmap.
Further reading
- ADR vs Decision Log vs RFC — the RFC-to-ADR pipeline for cross-team decisions, including when an RFC is required vs. optional
- ADR governance pattern — who has authority to make cross-team decisions and how to encode that authority in the ADR workflow
- ADR template in Markdown — the standard format that cross-team ADRs extend
- Decisions that never get written down — the "not building this" cross-team record type
- When to write an ADR — the threshold for documenting a decision, with cross-cutting impact as an explicit trigger
- The quarterly decision review — the triage pass where misclassified service-local ADRs get promoted to cross-team status
- How to export ChatGPT history — step one of recovering cross-team decision deliberation
- How to export Claude conversations — step one for Claude-side deliberation recovery