Start new work from the standard. If it truly does not fit, consult before you diverge. Then record the agreed exception as an ADR. Ask your Navigator, Security, or the CTO before making changes with a higher blast radius. An existing system that does not match this page is not, by itself, a reason to migrate.
What counts as “doesn’t fit”
The exception path is not the easy path. A deviation qualifies only when the standard is technically impossible on that platform, costs much more than the risk justifies, or conflicts with a hard external constraint. “It’s faster my way” does not qualify.
Every exception is time-boxed
A waiver has an owner, an expiry, and a review trigger. This stops it from becoming permanent without notice. One quarter is a common default. After that, renew the exception or bring the system into conformance. Each exception records a compensating control. This explains what reduces the risk of diverging and makes the trade-off clear.
Who approves
The approval level depends on the blast radius:
| Scope | Approver |
|---|---|
| Local, reversible deviation | Navigator |
| Auth, security, data handling, or the four-eyes/audit controls | Security or CTO |
The Secure SDLC (S-SDLC) controls these areas. They therefore need the higher level of approval.
Record it as an ADR
Use the ADR format. An exception ADR adds an expiry and a compensating control. Change the Status field to Deprecated when the exception expires, or Superseded when a new decision replaces it.
# ADR-014: Exception — service X skips the shared auth library
- Status: Accepted (expires 2026-Q4, review owner @team-lead)
- Deciders: Navigator, Security
- Context: legacy protocol needs mTLS the shared lib can't emit yet.
- Decision: use bespoke auth for X until lib v3 ships.
- Compensating control: network policy restricts X to the VPC; audit-log parity verified.
- Consequences: re-evaluate at lib v3; tracked in NT-XXXXX.stateDiagram-v2 direction LR [*] --> Requested Requested --> Approved: Navigator or Security or CTO Approved --> Active: time-boxed Active --> Expired: at expiry Expired --> Active: renewed Expired --> Conformed: remediated Active --> Superseded: folded into the standard Conformed --> [*] Superseded --> [*]
Keep a register
One register makes every active deviation and its expiry easy to audit. This is what an audit reviews:
| ADR | System | Standard waived | Owner | Approved by | Expires | Tracking |
|---|---|---|---|---|---|---|
| 014 | svc-x | shared auth lib | @team-lead | Security | 2026-Q4 | NT-XXXXX |
A pre-existing system that does not conform needs tracked remediation or an explicit risk-acceptance entry. Grandfathering is a recorded decision, not the absence of one.