# Documented non-adoption — a first-class outcome

> **Audience:** consumers (humans + AI agents) who have just
> read a `mgf-common` standard or recipe and find that adopting
> the prescribed primitive would harm their project.

This is a **principle**, not a MUST. It applies whenever a
consumer encounters an `mgf-common` feature whose default
behaviour conflicts with a deployment-coupled, policy-specific,
or shape-specific constraint. The principle says:

> **Documented non-adoption** is a first-class outcome of
> standards conformance work. A consumer that consciously
> declines a primitive AND records the rationale — in an ADR,
> a tracker entry, or a `FEEDBACK.md` paper — is **more**
> conformant than a consumer that adopts blindly and breaks a
> deployment constraint.

Promoted to a standalone document by
[ASPIRE-04](../../../FEEDBACK.md) in v0.20.0. The framing
already underwrote LOG-01 (cloud-native logging carve-out),
CONFIG-01 (framework-native config), and BOOTSTRAP-01 (Django
adoption blocker) — but the principle was implicit. Naming it
gives newer contributors cover to make the call AND nudges
them to file the carve-out so future consumers don't
re-derive.

**Magogi-foundation context.** The principle is broader than
mgf-common. It applies to every shared library that the Magogi
ecosystem produces — `mgf-apiprobe` (sibling), the future
`mgf-*` packages, plus any cornerstone library a consumer
project depends on. Consumers that decline-with-rationale make
the cornerstone library *better* by feeding back the gap;
consumers that adopt blindly hide the gap until production
breaks.

---

## What this principle says

A consumer's adoption of a `mgf-common` primitive ends in one
of three outcomes:

1. **Adopted.** The consumer wires the primitive as documented;
   the standards doc / recipe applies as written.
2. **Adopted with carve-out.** The consumer wires the primitive
   under a documented exemption (e.g., `bootstrap(setup_logging=
   False)`, `CONFIGURATION.md` §0a framework-native carve-out,
   `LOGGING.md` LG-06 cloud-native branch).
3. **Declined.** The consumer does NOT wire the primitive. The
   default behaviour conflicts with a constraint. The consumer
   records WHY in a project-side ADR, tracker entry, or feedback
   paper.

Outcomes 1, 2, and 3 are all **conformant at any level
(L1 / L2 / L3)** provided the rationale is recorded. The conformance bar is
"deliberate engineering decision," not "every primitive
adopted."

What is **NOT** conformant:

- **Silent non-adoption** ("we forgot to wire `Redactor`").
- **Adoption that breaks a deployment** ("we wired the JSON
  formatter; Grafana parsers stopped working; we don't know
  why our log volume dropped").
- **Indefinite deferral with no record** ("we'll get to it"
  for 18 months, no ADR, no tracker entry, no rationale).

---

## Three components: conscious decline, rationale, feedback

A documented non-adoption has three components. Each is
load-bearing.

### 1. Conscious decline

Not "we forgot." Not "we'll get to it." An explicit decision
made after **empirical** review (you tried it, it broke X) or
**architectural** review (you read the docs, it conflicts with
constraint Y).

A useful test: the decision should be defensible to a
hypothetical reviewer six months from now. "We didn't because
[concrete observation]" passes; "We didn't because the docs
were confusing" fails (the right outcome of confusing docs is
a `FEEDBACK.md` paper, not silent skip).

### 2. Documented rationale

Three valid recording shapes:

- **Project-side ADR.** The most durable shape. Lives in your
  project's `docs/adrs/` or equivalent. Names the primitive,
  the constraint that conflicted, the concrete observation,
  and the decision. A single-decision ADR is the typical
  shape; a compact multi-decision `MGF_ADOPTION.md` (one entry
  per primitive with disposition + rationale) works for a
  consumer declining several primitives at once.
- **Tracker entry.** GitHub issue, Jira ticket, Codeberg issue.
  Less durable (trackers churn), more lightweight. Use when
  the decision is reversible-soon ("we'll re-evaluate when
  v0.21 ships").
- **`FEEDBACK.md` paper upstream.** When the rationale points
  at a gap mgf-common could close (the constraint generalises
  to other consumers), the non-adoption becomes a
  **contribution**. File a paper; LOG-01 / CONFIG-01 /
  BOOTSTRAP-01 all originated this way.

The rationale should answer three questions:

- **What** primitive was declined?
- **Why** did adoption conflict (deployment-coupled? policy?
  shape mismatch? performance?)?
- **What** is the alternative implementation (and where does
  it live)?

### 3. Feedback if generalizable

If the rationale points at a gap that mgf-common could close,
file a paper. The non-adoption becomes a contribution.

Examples of generalizable gaps that became carve-outs:

- `JsonFormatter` declined for log-aggregator parser-coupling
  reasons → LOG-01 cloud-native carve-out in v0.18.0.
- `bootstrap()` (pre-v0.19.0) declined for Django-LOGGING
  dictConfig conflict → BOOTSTRAP-01 fix in v0.19.0.
- alembic autogenerate declined (worked around by
  hand-writing migrations) → PAPER-22 `include_object`
  pass-through in v0.19.0.

The contribution loop is the principle's load-bearing
property: every documented non-adoption is potential signal
for a future carve-out. Without the rationale, the signal is
lost.

---

## When to non-adopt

Non-adopt when adopting would:

- **Break a deployment-coupled contract.** Example: the
  formatter's wire shape conflicts with your log aggregator's
  parser (LOG-01).
- **Conflict with a policy constraint.** Example: your
  redaction key set diverges from `DEFAULT_REDACTION_KEYS` for
  legal/compliance reasons (e.g., a project that intentionally
  preserves an audit token under a key name `mgf-common`
  redacts by default).
- **Conflict with a framework's architectural assumption.**
  Example: your framework owns the seam mgf-common wants to
  install on (Django LOGGING dictConfig vs.
  `bootstrap()` handler install — BOOTSTRAP-01).
- **Add no value at the consumer's scale.** Example: the
  `versioned` file-store primitive at mgf-common's full shape
  is too heavy for a small consumer that has 50 lines of
  config (the "small consumer" scope discipline — adopt the
  slice you need; document the decline of the rest).
- **Cost more than the alternative.** Example: a 30-line
  drop-in replacement is genuinely simpler than wiring a
  500-line dependency. (Watch for this rationale being used
  as cover for laziness — see next §.)

---

## When NOT to non-adopt

Non-adoption is NOT cover for:

- **"We forgot."** Not conscious; not declined.
- **"It would take an hour to wire."** That's a cost, not a
  conflict. Wire it.
- **"Our project is special."** Specialness must be concrete
  (deployment-coupled, policy, framework architecture). If
  you can't name the conflict, the conflict probably isn't
  there.
- **"The docs are confusing."** Right outcome: a paper. Wrong
  outcome: silent skip.
- **"We'll get to it."** Right outcome: a tracker entry with
  a re-evaluation date. Wrong outcome: indefinite deferral.
- **"Adopting would force a refactor."** Refactors that
  improve conformance are conformance work. The principle
  protects deployment integrity, not refactor avoidance.

A useful sanity check: if your rationale would not survive a
review by a competent peer outside your team, the rationale
is probably "we forgot" or "it would take an hour" wearing a
costume.

---

## Worked examples (the historical carve-outs)

Three carve-outs have shipped using this principle. Each
originated as a single consumer's documented non-adoption that
generalised to a primitive change in mgf-common.

### LOG-01 — cloud-native logging shape (v0.18.0)

**Primitive declined:** `mgf.common.observability.JsonFormatter`
+ `Redactor` in their default shapes.

**Constraint:** a web consumer's deployment ships logs to a
log aggregator through a parser pipeline that depends on a
specific JSON wire shape (`{timestamp, level, logger,
message, extra: {...}}`). mgf-common's default shape was
`{ts, level, logger, msg, +flat extras}`. Adopting would have
broken every panel and alert rule overnight.

**Rationale recorded:** a project-side ADR ("decline
JsonFormatter; alternative is `<our shape>`"), with regression
tests pinning the shape and an empirical JSON-shape
divergence table.

**Generalizable gap?** Yes — every cloud-native consumer with
a deployment-coupled JSON parser hits the same constraint.

**Outcome:** LOG-01 shipped in v0.18.0 as the cloud-native
carve-out + the `docs/recipes/cloud-native-logging.md` recipe.
LG-06 grew an `applies_to:` annotation. The non-adoption
became a contribution that other consumers now benefit from.

### BOOTSTRAP-01 — framework-owned logging install (v0.19.0)

**Primitive declined (initial state):** `mgf.common.bootstrap()`.

**Constraints:**
1. `MgfSettings(env_prefix="MGF_", extra="forbid")` raised
   `ValidationError` against the project's shared `.env`
   (framework-prefixed keys like `SECRET_KEY` / `DB_*`
   triggered the strict-extra rejection).
2. `bootstrap()` unconditionally installed StreamHandler +
   RotatingFileHandler on root, conflicting with the
   framework's LOGGING dictConfig that had already configured
   the stack.

**Rationale recorded:** a project-side adoption log entry
explicitly stating "non-adoption until BOOTSTRAP-01 ships."

**Generalizable gap?** Yes. Both constraints generalise to
every framework-owned consumer (Django and similar); the
second generalises to FastAPI / Flask / Pyramid too.

**Outcome:** BOOTSTRAP-01 shipped in v0.19.0 (both fixes
additive: `dotenv_filtering="match_prefix"` default +
`setup_logging: bool = True` flag). The consumer flipped to
adopted-with-flag. A subsequent paper promoted the pattern
to the permanent
[`framework-owned-logging.md`](https://codeberg.org/magogi-admin/mgf-common/src/branch/main/docs/recipes/framework-owned-logging.md)
recipe.

### "Small consumer" scope discipline

**Primitives declined:** `VersionedFileStore[T]`, vault
backends beyond `env`, async logging machinery, and the
heaviest tier-C observability features.

**Constraint:** a small project (~3,000 LOC, 2 maintainers,
single-tenant) cannot sustain the cornerstone library's full
surface area. Wiring every primitive would dominate
maintenance budget.

**Rationale recorded:** a project-side `MGF_ADOPTION.md` §1
"we are a small consumer; here is the surface we adopt"
statement, with per-primitive disposition.

**Generalizable gap?** Partially. The concept of "small
consumer" surface as a documented adoption profile may
deserve its own recipe in a future release.

**Outcome:** the project gets the L1 conformance bar via the
adopted slice; documented decline of the rest preserves
conformance status because the rationale is recorded. Ships
fast and hasn't paid for surface it doesn't use.

---

## How to file the rationale

Three valid mechanisms, by durability:

### Project-side ADR

Most durable. Lives in `<project>/docs/adrs/<ADR-NNN>-<topic>.md`.

```markdown
# ADR-NNN — Decline X for <reason>

## Status
Accepted (2026-MM-DD).

## Context
<what mgf-common primitive is in scope; what constraint conflicts>

## Decision
We do not adopt <primitive>. Instead we <alternative implementation>.

## Consequences
<what the project gains; what the project gives up>

## Cross-references
- mgf-common <primitive> docs: <link>
- FEEDBACK.md paper (if filed): <link>
```

### Tracker entry

Lightweight. Use for reversible-soon decisions.

```
Title: Decline mgf-common <primitive> until <condition>
Body:
  - Constraint: <one paragraph>
  - Re-evaluation: <date OR mgf-common version>
  - Alternative implementation: <pointer>
```

### `FEEDBACK.md` paper

When the rationale points at a generalizable gap, file
upstream. See [`FEEDBACK.md`](../../../FEEDBACK.md) §1.4 for
the entry template.

---

## Cross-references

- [`audit-outcomes.md`](audit-outcomes.md) — the audit-time
  taxonomy that complements this adoption-time one. A `🚫
  declined-with-rationale` audit row's rationale flows through
  this principle's three-component recording shape.
- [`docs/standards/README.md`](../README.md) — the master
  conformance index. The "Conformance levels" section now
  cross-links to this principle.
- [`FEEDBACK.md`](../../../FEEDBACK.md) — the living canon of
  consumer entries. Search for `accept (...carve-out...)` or
  `Approach A` in shipped entries to see the pattern in
  practice.
- **LOG-01** (shipped v0.18.0) — the cloud-native logging-shape
  carve-out.
- **CONFIG-01** (shipped v0.18.0) — the framework-native config
  carve-out (frameworks that own their own config loader).
- **BOOTSTRAP-01** (shipped v0.19.0) — the framework-owned
  logging-install fix (additive `dotenv_filtering` +
  `setup_logging` flag).
- **ASPIRE-02** (shipped v0.18.0) — the strategic-review
  framing that "non-pain reading is also evidence." This
  principle is the formalisation.
