oe-sdk 0.1.0a1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- oe_sdk-0.1.0a1/.agents/skills/generate-adr/SKILL.md +233 -0
- oe_sdk-0.1.0a1/.agents/skills/generate-adr/evals/evals.json +33 -0
- oe_sdk-0.1.0a1/.agents/skills/generate-adr/references/anti-patterns.md +90 -0
- oe_sdk-0.1.0a1/.agents/skills/generate-adr/references/madr-template.md +100 -0
- oe_sdk-0.1.0a1/.github/copilot-instructions.md +431 -0
- oe_sdk-0.1.0a1/.github/workflows/ci.yml +202 -0
- oe_sdk-0.1.0a1/.github/workflows/nightly-integration.yml +68 -0
- oe_sdk-0.1.0a1/.github/workflows/publish-wiki.yml +22 -0
- oe_sdk-0.1.0a1/.github/workflows/publish.yml +23 -0
- oe_sdk-0.1.0a1/.gitignore +220 -0
- oe_sdk-0.1.0a1/.python-version +1 -0
- oe_sdk-0.1.0a1/CONTRIBUTING.md +179 -0
- oe_sdk-0.1.0a1/LICENSE +191 -0
- oe_sdk-0.1.0a1/PKG-INFO +281 -0
- oe_sdk-0.1.0a1/README.md +72 -0
- oe_sdk-0.1.0a1/docs/decisions/0001-modular-package-with-optional-extras-per-module.md +79 -0
- oe_sdk-0.1.0a1/docs/decisions/0002-pydantic-v2-for-configuration-models.md +88 -0
- oe_sdk-0.1.0a1/docs/decisions/0003-expose-raw-upstream-clients-no-wrappers-no-custom-exceptions.md +78 -0
- oe_sdk-0.1.0a1/docs/decisions/0004-native-sync-and-async-variants-per-io-module.md +84 -0
- oe_sdk-0.1.0a1/docs/decisions/0005-multi-use-context-managed-lifecycle-for-io-clients.md +62 -0
- oe_sdk-0.1.0a1/docs/decisions/0006-uv-as-build-backend-and-dependency-toolchain.md +99 -0
- oe_sdk-0.1.0a1/docs/decisions/0007-support-every-non-eol-cpython-minor.md +86 -0
- oe_sdk-0.1.0a1/docs/decisions/README.md +31 -0
- oe_sdk-0.1.0a1/prek.toml +27 -0
- oe_sdk-0.1.0a1/pyproject.toml +116 -0
- oe_sdk-0.1.0a1/src/oe_sdk/__init__.py +10 -0
- oe_sdk-0.1.0a1/src/oe_sdk/py.typed +0 -0
- oe_sdk-0.1.0a1/src/oe_sdk/s3/README.md +204 -0
- oe_sdk-0.1.0a1/src/oe_sdk/s3/__init__.py +30 -0
- oe_sdk-0.1.0a1/src/oe_sdk/s3/_aio.py +159 -0
- oe_sdk-0.1.0a1/src/oe_sdk/s3/_client.py +151 -0
- oe_sdk-0.1.0a1/src/oe_sdk/s3/_types.py +42 -0
- oe_sdk-0.1.0a1/src/oe_sdk/s3/_utils.py +55 -0
- oe_sdk-0.1.0a1/tests/s3/__init__.py +0 -0
- oe_sdk-0.1.0a1/tests/s3/integration/__init__.py +0 -0
- oe_sdk-0.1.0a1/tests/s3/integration/test_aio_localstack.py +47 -0
- oe_sdk-0.1.0a1/tests/s3/test_aio.py +173 -0
- oe_sdk-0.1.0a1/tests/s3/test_client.py +209 -0
- oe_sdk-0.1.0a1/tests/s3/test_utils.py +56 -0
- oe_sdk-0.1.0a1/tests/test_top_level_package.py +60 -0
- oe_sdk-0.1.0a1/uv.lock +1829 -0
- oe_sdk-0.1.0a1/wiki/Contributing.md +115 -0
- oe_sdk-0.1.0a1/wiki/Design-Principles.md +98 -0
- oe_sdk-0.1.0a1/wiki/Getting-Started.md +84 -0
- oe_sdk-0.1.0a1/wiki/Home.md +47 -0
- oe_sdk-0.1.0a1/wiki/Python-Support-and-Releases.md +66 -0
- oe_sdk-0.1.0a1/wiki/S3-Module.md +174 -0
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: generate-adr
|
|
3
|
+
description: |
|
|
4
|
+
Analyse changes on the current branch (versus the default branch) and draft
|
|
5
|
+
Markdown Architectural Decision Records (MADRs) into docs/decisions/.
|
|
6
|
+
Surfaces the architecturally significant choices made on the branch, proposes
|
|
7
|
+
one ADR per distinct decision, and writes NNNN-title.md files using the MADR
|
|
8
|
+
4.x template. Use whenever the user wants to record design rationale from a
|
|
9
|
+
branch, capture architecture decisions before opening a PR, produce ADRs, or
|
|
10
|
+
document a technology/library/pattern choice that has just landed in the
|
|
11
|
+
diff, even if the user does not explicitly say "ADR".
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
<aim>
|
|
15
|
+
|
|
16
|
+
Turn a branch's diff into durable design rationale. Read the changes versus
|
|
17
|
+
the default branch, spot the architecturally significant decisions, and write
|
|
18
|
+
them up as MADR-format records in `docs/decisions/`. One ADR per distinct
|
|
19
|
+
decision, numbered, assertive, and honest about trade-offs. Follow the spirit
|
|
20
|
+
of Olaf Zimmermann's ADR creation guidance: brief executive summaries,
|
|
21
|
+
considered options with real trade-offs, and a clear verdict.
|
|
22
|
+
|
|
23
|
+
</aim>
|
|
24
|
+
|
|
25
|
+
<preflight>
|
|
26
|
+
|
|
27
|
+
Run these checks first. Stop and report clearly if any fail.
|
|
28
|
+
|
|
29
|
+
1. **Inside a git repo with a clean enough state to diff:**
|
|
30
|
+
```bash
|
|
31
|
+
git rev-parse --is-inside-work-tree
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
2. **Not on the default branch** (nothing to diff against otherwise):
|
|
35
|
+
```bash
|
|
36
|
+
git branch --show-current
|
|
37
|
+
```
|
|
38
|
+
If the output matches the repo's default branch (`main`, `master`, or
|
|
39
|
+
whatever `origin/HEAD` resolves to), stop:
|
|
40
|
+
> "You're on the default branch, so there's no branch diff to analyse.
|
|
41
|
+
> Switch to a feature branch and rerun."
|
|
42
|
+
|
|
43
|
+
3. **Default branch is resolvable:**
|
|
44
|
+
```bash
|
|
45
|
+
git symbolic-ref refs/remotes/origin/HEAD 2>/dev/null | sed 's|refs/remotes/origin/||'
|
|
46
|
+
```
|
|
47
|
+
If this is empty, fall back to `main`. If `main` does not exist locally,
|
|
48
|
+
ask the user what the base branch should be.
|
|
49
|
+
|
|
50
|
+
</preflight>
|
|
51
|
+
|
|
52
|
+
## Workflow
|
|
53
|
+
|
|
54
|
+
### Step 1: Locate (or choose) the ADR directory
|
|
55
|
+
|
|
56
|
+
Probe for an existing ADR location in this order:
|
|
57
|
+
|
|
58
|
+
1. `docs/decisions/` (MADR's own convention)
|
|
59
|
+
2. `docs/adr/`
|
|
60
|
+
3. `docs/architecture/decisions/`
|
|
61
|
+
4. `adr/` at repo root
|
|
62
|
+
5. Any directory matching `**/NNNN-*.md` where `NNNN` is four digits
|
|
63
|
+
|
|
64
|
+
If more than one exists, use the one with the most files. If none exist,
|
|
65
|
+
default to `docs/decisions/` and create it on write.
|
|
66
|
+
|
|
67
|
+
Record the chosen directory. Scan it for the highest existing `NNNN` prefix
|
|
68
|
+
so the next ADR picks up from `NNNN + 1` (zero-padded to four digits).
|
|
69
|
+
|
|
70
|
+
### Step 2: Gather branch context
|
|
71
|
+
|
|
72
|
+
Run these in parallel:
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
BASE=$(git symbolic-ref refs/remotes/origin/HEAD 2>/dev/null | sed 's|refs/remotes/origin/||')
|
|
76
|
+
BASE=${BASE:-main}
|
|
77
|
+
|
|
78
|
+
if git show-ref --verify --quiet "refs/remotes/origin/${BASE}"; then
|
|
79
|
+
BASE_REF="origin/${BASE}"
|
|
80
|
+
elif git show-ref --verify --quiet "refs/heads/${BASE}"; then
|
|
81
|
+
BASE_REF="${BASE}"
|
|
82
|
+
else
|
|
83
|
+
echo "Could not resolve base branch: ${BASE}" >&2
|
|
84
|
+
exit 1
|
|
85
|
+
fi
|
|
86
|
+
|
|
87
|
+
git log --no-pager "${BASE_REF}..HEAD" --oneline
|
|
88
|
+
git diff --no-pager --stat "${BASE_REF}...HEAD"
|
|
89
|
+
git diff --no-pager "${BASE_REF}...HEAD"
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### Step 3: Identify architecturally significant decisions
|
|
93
|
+
|
|
94
|
+
Read the diff and extract the decisions that deserve a record. Signals to
|
|
95
|
+
look for, roughly in descending order of significance:
|
|
96
|
+
|
|
97
|
+
- New or swapped runtime dependencies (package.json, pyproject.toml,
|
|
98
|
+
requirements.txt, go.mod, Cargo.toml, Gemfile, etc.)
|
|
99
|
+
- New top-level modules, packages, or services
|
|
100
|
+
- Database schema changes, new migrations, new storage engines
|
|
101
|
+
- New or changed external contracts: API endpoints, event schemas,
|
|
102
|
+
message formats, SDK versions
|
|
103
|
+
- Infrastructure changes: Terraform, Helm, Dockerfiles, CI configs that
|
|
104
|
+
shift where or how the system runs
|
|
105
|
+
- Replacement of an existing implementation (the "we used X, now we use Y"
|
|
106
|
+
shape)
|
|
107
|
+
- Introduction of a new cross-cutting pattern: caching, async/queues,
|
|
108
|
+
auth/authz, feature flags, observability
|
|
109
|
+
- Non-trivial changes to shared abstractions, base classes, or protocols
|
|
110
|
+
|
|
111
|
+
Ignore pure refactors, formatting, lockfile-only changes, and typo fixes
|
|
112
|
+
unless the commit messages frame them as intentional decisions.
|
|
113
|
+
|
|
114
|
+
Group related changes into a single decision. A single ADR can span many
|
|
115
|
+
files if they all serve one choice (e.g. "adopt Redis for rate limiting"
|
|
116
|
+
might touch code, tests, Helm values, and a dependency file). Don't split
|
|
117
|
+
one decision into multiple ADRs just because it is wide.
|
|
118
|
+
|
|
119
|
+
### Step 4: Propose the ADR slate
|
|
120
|
+
|
|
121
|
+
Present the proposed ADRs to the user as a short list. For each entry give:
|
|
122
|
+
|
|
123
|
+
- A working title (imperative, specific, no filler)
|
|
124
|
+
- One sentence framing the problem
|
|
125
|
+
- The files or areas of the diff that motivate it
|
|
126
|
+
|
|
127
|
+
Then ask:
|
|
128
|
+
|
|
129
|
+
> "Here's what I'd like to record. Shall I draft all of them, or do you want
|
|
130
|
+
> to drop, merge, or add any? You can also tell me to write a specific one
|
|
131
|
+
> first."
|
|
132
|
+
|
|
133
|
+
Honour edits. If the user merges two proposals, keep the combined decision's
|
|
134
|
+
scope in mind when drafting. If they drop one, drop it fully.
|
|
135
|
+
|
|
136
|
+
### Step 5: For each approved decision, draft the ADR
|
|
137
|
+
|
|
138
|
+
Follow the MADR 4.x template (see `references/madr-template.md` for the
|
|
139
|
+
full canonical form). Every ADR must have:
|
|
140
|
+
|
|
141
|
+
- YAML frontmatter with `status: proposed`, `date: <today, YYYY-MM-DD>`,
|
|
142
|
+
and `decision-makers` set to the branch's commit authors (dedup, drop
|
|
143
|
+
`[bot]` accounts).
|
|
144
|
+
- A short, descriptive H1 title.
|
|
145
|
+
- `## Context and Problem Statement` — two or three sentences. Use terms
|
|
146
|
+
from the domain vocabulary visible in the diff. Frame the problem as a
|
|
147
|
+
question where possible; you want readers curious.
|
|
148
|
+
- `## Decision Drivers` — bullets covering the forces that shaped the
|
|
149
|
+
decision (quality attributes, constraints, existing conventions in the
|
|
150
|
+
repo). Keep them specific to the situation, not generic.
|
|
151
|
+
- `## Considered Options` — at least two, ideally three. One of them must
|
|
152
|
+
be a real alternative; placeholder "do nothing" options are fine only if
|
|
153
|
+
they genuinely reflect a status quo worth weighing. Read the diff for
|
|
154
|
+
clues about what was *not* chosen (e.g. imports that were considered,
|
|
155
|
+
libraries mentioned in comments, removed code that hints at prior attempts).
|
|
156
|
+
- `## Decision Outcome` — a single sentence naming the chosen option and
|
|
157
|
+
the primary reason. Assertive voice. No hedging.
|
|
158
|
+
- `### Consequences` — mix good and bad, at least one of each. Cover
|
|
159
|
+
operational and maintenance impact, not only developer ergonomics.
|
|
160
|
+
- `### Confirmation` — how you'd verify the decision was actually adopted
|
|
161
|
+
(tests, metrics, CI checks, code review rules). Concrete if possible.
|
|
162
|
+
- `## Pros and Cons of the Options` — one subsection per considered option
|
|
163
|
+
with a short description plus bulleted pros and cons. This is what lets a
|
|
164
|
+
reader in six months see the trade-space.
|
|
165
|
+
- `## More Information` — optional. Only include links and references that
|
|
166
|
+
genuinely help (issue trackers, vendor docs, prior ADRs). Skip if empty;
|
|
167
|
+
don't pad.
|
|
168
|
+
|
|
169
|
+
File name: `NNNN-title-with-dashes.md`, lowercase, four-digit prefix
|
|
170
|
+
continuing the repo's sequence, kebab-case title derived from the ADR's H1.
|
|
171
|
+
|
|
172
|
+
### Step 6: Write each ADR and confirm
|
|
173
|
+
|
|
174
|
+
Write the files with `mkdir -p <adr-dir>` as needed. Then summarise back to
|
|
175
|
+
the user:
|
|
176
|
+
|
|
177
|
+
```
|
|
178
|
+
Drafted <N> ADR(s) in <adr-dir>:
|
|
179
|
+
<NNNN>-<slug>.md — <title>
|
|
180
|
+
...
|
|
181
|
+
|
|
182
|
+
Each is marked `status: proposed`. Review, edit as you see fit, and flip the
|
|
183
|
+
status to `accepted` when you're ready.
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
### Step 7: Offer to commit
|
|
187
|
+
|
|
188
|
+
Ask the user whether they'd like the ADRs committed to the current branch:
|
|
189
|
+
|
|
190
|
+
> "Do you want me to commit these ADRs to the current branch? I'll only stage
|
|
191
|
+
> the new files, not anything else you have in flight. Reply 'yes' to commit,
|
|
192
|
+
> or 'no' to leave them unstaged for you to handle."
|
|
193
|
+
|
|
194
|
+
If the user says yes:
|
|
195
|
+
|
|
196
|
+
```bash
|
|
197
|
+
git add <adr-dir>/<NNNN>-<slug>.md ...
|
|
198
|
+
git commit -m "docs(adr): add <N> ADR(s) for <branch-name>" \
|
|
199
|
+
-m "<bullet list of ADR titles>"
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
Use only the new ADR paths in the `git add` invocation so nothing else the
|
|
203
|
+
user has staged or modified gets pulled in. Report the commit SHA back.
|
|
204
|
+
|
|
205
|
+
If the user says no (or anything other than yes), leave the files on disk
|
|
206
|
+
unstaged and confirm:
|
|
207
|
+
|
|
208
|
+
> "Left the ADRs unstaged. Review and commit when you're ready."
|
|
209
|
+
|
|
210
|
+
Do not push. Do not open a PR. That's a separate workflow.
|
|
211
|
+
|
|
212
|
+
## Tone and quality guardrails
|
|
213
|
+
|
|
214
|
+
Before you finalise each ADR, check it against the anti-patterns in
|
|
215
|
+
`references/anti-patterns.md`. Specifically:
|
|
216
|
+
|
|
217
|
+
- No marketing language or unsubstantiated superlatives.
|
|
218
|
+
- At least one real alternative, not a straw-man.
|
|
219
|
+
- Cost and risk stated alongside benefit.
|
|
220
|
+
- Confidence level honest; if you're unsure, say `status: proposed` and
|
|
221
|
+
note the uncertainty in `## More Information`.
|
|
222
|
+
- Keep the whole thing tight. If a section has nothing to say, omit it.
|
|
223
|
+
Empty headings are worse than no heading.
|
|
224
|
+
|
|
225
|
+
The ADR is meant to read like a journal entry from the decision maker:
|
|
226
|
+
specific, grounded in the actual diff, and useful to whoever reads it next
|
|
227
|
+
quarter when something breaks.
|
|
228
|
+
|
|
229
|
+
## Reference files
|
|
230
|
+
|
|
231
|
+
- `references/madr-template.md` — full MADR 4.x template with placeholders.
|
|
232
|
+
- `references/anti-patterns.md` — Zimmermann's ADR anti-patterns with
|
|
233
|
+
examples; consult before finalising any ADR.
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
{
|
|
2
|
+
"skill_name": "generate-adr",
|
|
3
|
+
"evals": [
|
|
4
|
+
{
|
|
5
|
+
"id": 1,
|
|
6
|
+
"name": "single-decision-library-swap",
|
|
7
|
+
"prompt": "I'm on a feature branch where I swapped our in-house retry logic for the `tenacity` library across the HTTP client layer. I've also added `tenacity>=8.2` to pyproject.toml, removed the old retry/ module, and updated three call sites. Generate any ADRs you think this branch warrants.",
|
|
8
|
+
"expected_output": "A single ADR in docs/decisions/ (NNNN-<slug>.md) using MADR format, capturing the decision to adopt tenacity over the in-house retry helper. Should include at least two considered options (tenacity, keep in-house, optionally backoff/other libs), real trade-offs, and a confirmation strategy. Skill should also ask whether to commit.",
|
|
9
|
+
"files": []
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
"id": 2,
|
|
13
|
+
"name": "multi-decision-branch",
|
|
14
|
+
"prompt": "This branch does two things: (1) introduces Redis for distributed rate limiting (new redis dependency, new helm values block, new RateLimiter abstraction) and (2) moves our background jobs off threading onto asyncio with a new asyncio.TaskGroup-based runner. Record these properly.",
|
|
15
|
+
"expected_output": "Two separate ADRs in docs/decisions/, numbered sequentially. One for the Redis-based rate limiter decision, one for the asyncio concurrency model. Each self-contained, neither trying to cover the other. Skill should also ask whether to commit.",
|
|
16
|
+
"files": []
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
"id": 3,
|
|
20
|
+
"name": "database-technology-choice",
|
|
21
|
+
"prompt": "I'm introducing a new service that needs a primary datastore. On this branch I've picked Postgres, added migrations, and wired up SQLAlchemy. Draft the ADR.",
|
|
22
|
+
"expected_output": "A single ADR using MADR. Must name at least two real alternatives (e.g. MySQL, SQLite, a managed option, or a document store) rather than a straw-man. Decision drivers should reference operational concerns (backups, team familiarity, managed service availability), not just developer ergonomics.",
|
|
23
|
+
"files": []
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
"id": 4,
|
|
27
|
+
"name": "refactor-only-branch",
|
|
28
|
+
"prompt": "This branch renames a bunch of functions, moves some modules around, and fixes typos. Generate ADRs for it.",
|
|
29
|
+
"expected_output": "The skill should recognise there are no architecturally significant decisions here and respond by saying so, rather than inventing an ADR. If it does write anything, it should be at most one ADR clearly scoped to a meaningful decision, not one per rename.",
|
|
30
|
+
"files": []
|
|
31
|
+
}
|
|
32
|
+
]
|
|
33
|
+
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
# ADR anti-patterns
|
|
2
|
+
|
|
3
|
+
Adapted from Olaf Zimmermann's "How to create Architectural Decision Records
|
|
4
|
+
— and how not to" (ozimmer.ch, 2023). Consult this list before finalising
|
|
5
|
+
any ADR. If a draft smells like one of these, rewrite it.
|
|
6
|
+
|
|
7
|
+
## Subjectivity patterns
|
|
8
|
+
|
|
9
|
+
### Fairy Tale (Wishful Thinking)
|
|
10
|
+
|
|
11
|
+
A shallow justification with only upsides. Pros listed, cons absent.
|
|
12
|
+
|
|
13
|
+
Bad: "We decided for a load balancer because it balances load, which is a
|
|
14
|
+
good thing."
|
|
15
|
+
|
|
16
|
+
Fix: name at least one concrete cost, risk, or trade-off. If you truly can't
|
|
17
|
+
find one, you're not looking hard enough, or the decision isn't worth a
|
|
18
|
+
record.
|
|
19
|
+
|
|
20
|
+
### Sales Pitch
|
|
21
|
+
|
|
22
|
+
Marketing language. Adjectives and adverbs that can't be backed by evidence.
|
|
23
|
+
|
|
24
|
+
Bad: "We chose this outstanding technology because it is unrivalled in the
|
|
25
|
+
marketplace; its splendid performance shines everywhere."
|
|
26
|
+
|
|
27
|
+
Fix: delete every adjective and adverb you can't substantiate. Link to the
|
|
28
|
+
benchmark, issue tracker, or prior experience that supports the claim, or
|
|
29
|
+
remove the claim.
|
|
30
|
+
|
|
31
|
+
### Free Lunch Coupon
|
|
32
|
+
|
|
33
|
+
No consequences documented, or only trivially harmless ones. Long-term and
|
|
34
|
+
operational costs hidden.
|
|
35
|
+
|
|
36
|
+
Bad: "We decided for event-based architecture because it decouples the
|
|
37
|
+
communication participants."
|
|
38
|
+
|
|
39
|
+
Fix: explicitly name the design, test, and operational cost. Mention who
|
|
40
|
+
pays it (developers, on-call, consumers of the API).
|
|
41
|
+
|
|
42
|
+
### Dummy Alternative
|
|
43
|
+
|
|
44
|
+
A fake option to make the preferred choice shine.
|
|
45
|
+
|
|
46
|
+
Bad: "We decided to use Postgres. We could implement our own relational
|
|
47
|
+
database, but this takes time and effort."
|
|
48
|
+
|
|
49
|
+
Fix: find a real alternative. For most decisions there's at least one
|
|
50
|
+
industry-standard competitor worth naming. If there genuinely isn't,
|
|
51
|
+
explain why — that's the actual decision.
|
|
52
|
+
|
|
53
|
+
## Time-dimension patterns
|
|
54
|
+
|
|
55
|
+
### Sprint (Rush)
|
|
56
|
+
|
|
57
|
+
Only one option. Only short-term consequences considered.
|
|
58
|
+
|
|
59
|
+
Fix: search for alternatives (online, professional networks, the team's own
|
|
60
|
+
history). Report on the search, even briefly. Add at least a sentence on
|
|
61
|
+
mid-term consequences.
|
|
62
|
+
|
|
63
|
+
### Tunnel Vision
|
|
64
|
+
|
|
65
|
+
Local view only. Developer experience covered, operations and maintenance
|
|
66
|
+
ignored.
|
|
67
|
+
|
|
68
|
+
Fix: name sysadmins, SREs, and maintainers explicitly in Decision Drivers
|
|
69
|
+
or Consequences. Score the chosen solution against manageability and
|
|
70
|
+
evolvability.
|
|
71
|
+
|
|
72
|
+
### Maze
|
|
73
|
+
|
|
74
|
+
Topic drifts. Discussion centres on irrelevant detail.
|
|
75
|
+
|
|
76
|
+
Fix: keep the title and problem statement in view while writing. If a
|
|
77
|
+
paragraph doesn't serve the stated question, cut it.
|
|
78
|
+
|
|
79
|
+
## Quality checklist
|
|
80
|
+
|
|
81
|
+
Before marking an ADR ready for review:
|
|
82
|
+
|
|
83
|
+
- Does every adjective earn its place?
|
|
84
|
+
- Is there at least one genuine alternative?
|
|
85
|
+
- Is there at least one real trade-off in Consequences?
|
|
86
|
+
- Would an operator or maintainer recognise their concerns in the ADR?
|
|
87
|
+
- If someone asked "why this, not that?" in review, is the answer already
|
|
88
|
+
in the document?
|
|
89
|
+
- Is the word count proportionate to the stakes? One page for routine
|
|
90
|
+
choices; a few pages only when the problem is genuinely wicked.
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
# MADR 4.x Template
|
|
2
|
+
|
|
3
|
+
Use this as the canonical template when drafting a new ADR. Remove any
|
|
4
|
+
optional sections (marked below) that you don't need, rather than leaving
|
|
5
|
+
them empty.
|
|
6
|
+
|
|
7
|
+
```markdown
|
|
8
|
+
---
|
|
9
|
+
# status options: proposed | rejected | accepted | deprecated | superseded by ADR-NNNN
|
|
10
|
+
status: proposed
|
|
11
|
+
date: YYYY-MM-DD
|
|
12
|
+
decision-makers: [list of people involved in the decision]
|
|
13
|
+
# consulted: [optional list of SMEs and others with two-way communication]
|
|
14
|
+
# informed: [optional list of people kept up-to-date, one-way communication]
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
# {short title, representative of solved problem and found solution}
|
|
18
|
+
|
|
19
|
+
## Context and Problem Statement
|
|
20
|
+
|
|
21
|
+
{Describe the context and problem statement in two or three sentences, or as
|
|
22
|
+
an illustrative story. Frame the problem as a question where possible, and
|
|
23
|
+
link to issue trackers or design docs where useful.}
|
|
24
|
+
|
|
25
|
+
## Decision Drivers
|
|
26
|
+
|
|
27
|
+
* {driver 1, e.g. a force, facing concern, quality attribute}
|
|
28
|
+
* {driver 2}
|
|
29
|
+
* ...
|
|
30
|
+
|
|
31
|
+
## Considered Options
|
|
32
|
+
|
|
33
|
+
* {title of option 1}
|
|
34
|
+
* {title of option 2}
|
|
35
|
+
* {title of option 3}
|
|
36
|
+
|
|
37
|
+
## Decision Outcome
|
|
38
|
+
|
|
39
|
+
Chosen option: "{title of option 1}", because {justification: e.g. only
|
|
40
|
+
option that meets a k.o. criterion; resolves a key driver; comes out best
|
|
41
|
+
when weighed against the others}.
|
|
42
|
+
|
|
43
|
+
### Consequences
|
|
44
|
+
|
|
45
|
+
* Good, because {positive consequence, e.g. improvement of a desired quality}
|
|
46
|
+
* Bad, because {negative consequence, e.g. cost, complexity, new failure mode}
|
|
47
|
+
* ...
|
|
48
|
+
|
|
49
|
+
### Confirmation
|
|
50
|
+
|
|
51
|
+
{How will implementation of and compliance with this decision be confirmed?
|
|
52
|
+
Code review rules, automated tests, CI checks, a dashboard metric, a runbook
|
|
53
|
+
reference. Concrete if possible.}
|
|
54
|
+
|
|
55
|
+
## Pros and Cons of the Options
|
|
56
|
+
|
|
57
|
+
### {title of option 1}
|
|
58
|
+
|
|
59
|
+
{description, 1-2 sentences, or a link}
|
|
60
|
+
|
|
61
|
+
* Good, because {argument}
|
|
62
|
+
* Good, because {argument}
|
|
63
|
+
* Neutral, because {argument}
|
|
64
|
+
* Bad, because {argument}
|
|
65
|
+
|
|
66
|
+
### {title of option 2}
|
|
67
|
+
|
|
68
|
+
{description}
|
|
69
|
+
|
|
70
|
+
* Good, because {argument}
|
|
71
|
+
* Bad, because {argument}
|
|
72
|
+
|
|
73
|
+
### {title of option 3}
|
|
74
|
+
|
|
75
|
+
{description}
|
|
76
|
+
|
|
77
|
+
* Good, because {argument}
|
|
78
|
+
* Bad, because {argument}
|
|
79
|
+
|
|
80
|
+
## More Information
|
|
81
|
+
|
|
82
|
+
{Optional. Links to related ADRs, vendor documentation, benchmarks, issue
|
|
83
|
+
trackers, prior art. Omit the section entirely if there's nothing worth
|
|
84
|
+
linking.}
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## File naming
|
|
88
|
+
|
|
89
|
+
- Pattern: `NNNN-title-with-dashes.md`
|
|
90
|
+
- `NNNN` is a zero-padded four-digit sequence (`0001`, `0002`, ...)
|
|
91
|
+
- Title is kebab-case, lowercase, derived from the ADR's H1
|
|
92
|
+
- Example: `0007-use-postgres-for-rate-limiter-state.md`
|
|
93
|
+
|
|
94
|
+
## Status lifecycle
|
|
95
|
+
|
|
96
|
+
- `proposed` — drafted, not yet agreed
|
|
97
|
+
- `accepted` — agreed and being enacted
|
|
98
|
+
- `rejected` — considered and ruled out
|
|
99
|
+
- `deprecated` — no longer applicable
|
|
100
|
+
- `superseded by ADR-NNNN` — a later ADR replaces this one
|