# Reliability & Accuracy

> **Status:** v0.1 — first pass, finalized 2026-05-15
> (review-pass verified all file:line citations against the
> live source). Last updated 2026-05-15.
> A federation-sibling-scoped reliability audit: sampled the
> load-bearing files (`core/suite.py`, `core/probe.py`,
> `auth/flows.py`, `transport/httpx_transport.py`,
> `checks/security.py`, `checks/contract.py`) end-to-end +
> spot-checked the matchers and the CLI against the **RA** /
> **EH** / **SC** rule set from `mgf-standard/docs/standards/`.
> The sibling's surface (~5000 LOC across 45 files) is the
> largest in the federation; the audit prioritises systemic
> patterns over exhaustive per-file enumeration.
>
> **Scope:** v1.0 readiness for mgf-apiprobe.
> **Audience:** the maintainer + future AI agents.
> **Cross-references:** [`PUBLIC_API.md`](../../PUBLIC_API.md),
> [`DESIGN.md`](../../DESIGN.md),
> [`docs/standards/SCOPE.md`](../standards/SCOPE.md),
> [`docs/standards/README.md`](../standards/README.md),
> [`mgf-common/docs/inprogress/RELIABILITY_AND_ACCURACY.md`](https://codeberg.org/magogi-admin/mgf-common/src/branch/main/docs/inprogress/RELIABILITY_AND_ACCURACY.md)
> (cornerstone),
> [`mgf-http/docs/inprogress/RELIABILITY_AND_ACCURACY.md`](https://codeberg.org/magogi-admin/mgf_http/src/branch/main/docs/inprogress/RELIABILITY_AND_ACCURACY.md)
> (sister-sibling — the transport layer has parallel concerns).

The sibling is at v0.3.0 (post-v2.6/v2.7 compliance bump from
v0.2.1). It is the verification harness for REST APIs — the
"is the provider behaving correctly" tool. A reliability gap
here means false-negative findings (regression slips through)
or false-positive findings (operator-trust erodes).

---

## §1 You are here

mgf-apiprobe ships a large surface across `core/` (Probe,
Suite, Check, Context, Transport, Response, Finding, Report,
Matcher), `auth/` (BearerAuth, BasicAuth, CookieAuth,
ApiKeyAuth, ChainedAuth, NullAuth), `checks/` (5 modules:
contract, security, quality, observability, schema),
`factories/` (test-data generators), `transport/` (httpx
backend), and `reporting/` (human + JSON writers). `mypy
--strict` clean; ruff clean; the test suite covers
`tests/unit/`, `tests/integration/`, `tests/public_surface/`.

What this tracker exposes is the **orchestration shape** —
the patterns at the seams between probes / checks / transport
where surprising behaviour could surface in adversarial or
edge-case suite configurations: a check that raises, a
transport that flaps, two probes with the same id, a
severity override applied silently, an auth flow whose env
var is intentionally empty.

**Counts (2026-05-17):**

| Priority | Open | Closed | Total |
|---|---|---|---|
| P0 — v1.0 surface-lock blockers | 0 | 0 | 0 |
| P1 — should land before/with v1.0 | 0 | 3 | 3 |
| P2 — post-v1.0 hardening | 3 | 1 | 4 |
| **Total** | **3** | **4** | **7** |

**Do first:** RA-01..03 closed (P1). RA-04 closed (P2,
2026-05-17 — cookie CR/LF guard was already shipped per the
existing `_assert_no_crlf_in_cookies` call in `httpx_transport.py`
+ unit test). RA-05/06/07 deferred to v1.1+ — small but real
code changes (kwargs, pool eviction strategy) better validated
post-v1.0 against real consumer feedback.

---

## §2 Priority table

| ID | Concern | One-line | Effort | Status |
|---|---|---|---|---|
| [**RA-01**](#ra-01-asyncio-gather-without-return-exceptions) | Concurrency / failure isolation | `Suite.run` calls `asyncio.gather(*(_execute(p) for p in probes_to_run))` without `return_exceptions=True`. `_run_one_probe` catches `TransportError` internally, but a `Check.run` that raises (or any other unexpected exception) cancels all sibling probes. | S | ✅ closed |
| [**RA-02**](#ra-02-probe-id-uniqueness-not-enforced) | Suite-level invariant | `Suite.__init__` accepts `probes: Sequence[Probe]` and stores as a tuple without dedup. Two probes with the same `probe_id` produce findings keyed identically — operators reading the report can't disambiguate. `SuiteLogicError` is documented for this case but isn't actually raised. | S | ✅ closed |
| [**RA-03**](#ra-03-severity-override-audit-log) | Auditability of policy changes | `_apply_severity_override` returns a new `Finding` with mutated severity, no log line. A suite that overrides a CRITICAL → WARN finding hides the original severity from the report consumer. DESIGN.md §3.2.2 explicitly defers the audit log to v0.4. | XS | ✅ closed |
| [**RA-04**](#ra-04-cookie-value-sanitization) | Defensive input handling | `HttpxTransport.send` builds `request_cookies = dict(creds.cookies)` then passes to httpx. Same `\r\n` injection class as mgf-http RA-03. Operator-supplied probe config is usually trusted; defence-in-depth catches the rare gap. | XS | ✅ closed |
| [**RA-05**](#ra-05-follow-redirects-true-in-api-verification) | Verification-target drift | `HttpxTransport.__init__` sets `follow_redirects=True`. For a verification harness this can MASK the real issue — if `/api/v1/users` 302s to `/api/v2/users`, the test was supposed to verify v1 but actually verifies v2. | XS | ⏳ v1.1+ — add `follow_redirects=` kwarg pass-through |
| [**RA-06**](#ra-06-httpx-client-pool-reuse-across-suites) | Resource hygiene | `HttpxTransport` holds one httpx client instance with its connection pool. Reused across `Suite.run()` calls. For suites probing many distinct hosts, the pool grows; no eviction strategy. | S | ⏳ v1.1+ — needs real consumer feedback to size the eviction strategy |
| [**RA-07**](#ra-07-empty-credential-treated-as-unset) | Policy clarity | `_resolve_credential` rejects `value == ""` as "unset or empty." Some auth flows use intentionally-empty values (e.g., test-mode bearers, anonymous-tier API keys). The error message says "unset or empty" but treats them identically. | XS | ⏳ v1.1+ — `allow_empty=` kwarg on flow constructors |

Effort scale: XS (≤ 15 min); S (≤ 1 h); M (≤ 1 session).

---

## §3 Invariants we hold

The list of "closed elsewhere; do not re-open":

- **RA-INV-1** — Transport errors yield **synthetic Findings**,
  don't propagate. `Suite._run_one_probe` catches `TransportError`
  at [`suite.py:144-166`](../../src/mgf/apiprobe/core/suite.py#L144)
  and emits a `RootCause.NETWORK` Finding. Per DESIGN.md §3.5.
- **RA-INV-2** — Auth-flow config errors raise at **suite-build
  time**; secret-resolution errors raise at **run time**. The
  split is intentional: a missing `token=` / `env=` is a
  programmer error (raised in `__init__`); a missing env var
  is a deployment error (raised in `prepare()`). At
  [`auth/flows.py:20-50`](../../src/mgf/apiprobe/auth/flows.py#L20).
- **RA-INV-3** — `Finding` is a **frozen dataclass**;
  `_apply_severity_override` uses `dataclasses.replace`
  ([`suite.py:174-187`](../../src/mgf/apiprobe/core/suite.py#L174))
  rather than mutating in place. Immutability of report content
  is preserved.
- **RA-INV-4** — Probe execution is **concurrency-capped**
  via `asyncio.Semaphore(self.settings.max_concurrency)`
  ([`suite.py:109`](../../src/mgf/apiprobe/core/suite.py#L109)).
  A 1000-probe suite doesn't fan out 1000 concurrent connections.
- **RA-INV-5** — `HttpxTransport` closes its httpx client via
  `aclose()`
  ([`httpx_transport.py:77-78`](../../src/mgf/apiprobe/transport/httpx_transport.py#L77)).
  Async context manager + explicit `aclose()` shapes both
  supported.
- **RA-INV-6** — Suite-level fields are **stored as tuples**
  (`self.probes`, `self.checks`)
  ([`suite.py:78-79`](../../src/mgf/apiprobe/core/suite.py#L78)).
  Mutation-after-construction is structurally prevented.
- **RA-INV-7** — `severity_overrides` is **applied per-finding**
  by code, not by check-result. Two checks emitting the same
  finding code both pick up the override. Documented at
  DESIGN.md §3.2.2.

---

## §4 Work units

### RA-01 `asyncio.gather` without `return_exceptions`

**Why:** `Suite.run`
([`suite.py:115`](../../src/mgf/apiprobe/core/suite.py#L115)):

```python
results = await asyncio.gather(*(_execute(p) for p in probes_to_run))
```

Per Python asyncio semantics: when one coroutine in a `gather`
raises, the OTHER coroutines are NOT cancelled (per default),
but the gather itself raises the first exception. In practice
`asyncio.gather` propagates the first exception and the rest
of the gathered coroutines run to completion in the
background, but their results are LOST (the gather doesn't
return them).

For a Suite with N probes:

- Probe `_execute` calls `_run_one_probe(...)`.
- `_run_one_probe` catches `TransportError` and returns
  synthetic findings.
- But `_run_one_probe` also runs `check.run(probe, response, ctx)`
  for each check. Per the `Check` Protocol, `run` is permitted
  to raise (e.g., a malformed regex in `schema.py` raising,
  a JSON-parse failure in `contract.py` raising).
- An uncaught exception in `check.run` propagates up from
  `_run_one_probe` → `_execute` → `gather` → cancels the
  return-of-the-others.

Concrete impact: a bug in one check (or one probe with
weird response shape that hits a check edge case) hides the
findings of every other probe in the suite. The report shows
"only one probe ran" even though N-1 probes completed.

Per **EH-04** + **RA-02** in mgf-common (RA-02 closed the same
class for `bootstrap()`'s rollback chain): defensive shape +
return_exceptions + per-task error translation.

**Concrete output:**

- Wrap `_run_one_probe` with a try/except `Exception` that
  catches any non-cancellation exception, logs it at
  WARNING level, and returns a synthetic Finding shape:
  ```python
  async def _execute(probe):
      async with semaphore:
          try:
              return await self._run_one_probe(probe, ctx, transport)
          except Exception as exc:
              _LOGGER.warning("probe %s failed unexpectedly: %s",
                              probe.probe_id, exc, exc_info=True)
              return [Finding(
                  code="suite.probe.exception",
                  severity=Severity.CRITICAL,
                  root_cause=RootCause.UNKNOWN,
                  message=f"Probe execution raised {type(exc).__name__}: {exc}",
                  ...
              )], False
  ```
- Also: use `asyncio.gather(..., return_exceptions=True)` as
  belt-and-suspenders.
- Add a test: a Check that raises a custom exception; assert
  the report contains findings from all sibling probes + the
  synthetic-exception finding for the buggy check.

**Locked in by:** the new test fails on first run if either
the defensive wrap OR `return_exceptions=True` is dropped.

**Cross-references:** EH-04 (top-level handlers); RA-02 in
mgf-common (rollback-chain failure injection — same defensive
pattern); ERROR_HANDLING.md §11.2 (gather with
return_exceptions).

---

### RA-02 Probe-id uniqueness not enforced

**Why:** `Suite.__init__`
([`suite.py:68-81`](../../src/mgf/apiprobe/core/suite.py#L68)):

```python
def __init__(self, *, probes, checks, settings=None, severity_overrides=None):
    self.probes: tuple[Probe, ...] = tuple(probes)
    ...
```

No check for duplicate `probe.probe_id`. Two probes with the
same id:

- Both run independently.
- Both emit Findings with `finding.probe_id == "<duplicate>"`.
- The Report's per-probe summary section (or any consumer
  filtering by `probe_id`) gets confused.

`PUBLIC_API.md` documents `SuiteLogicError` as "Raised when
... two primitives collide on the same identifier" — but
the runtime doesn't actually raise it for probes.

**Concrete output:**

- In `Suite.__init__`, after building the tuple, walk and
  check for `probe.probe_id` collisions:
  ```python
  seen: set[str] = set()
  for p in self.probes:
      if p.probe_id in seen:
          raise SuiteLogicError(
              f"probe_id collision: two probes share id "
              f"{p.probe_id!r}"
          )
      seen.add(p.probe_id)
  ```
- Same check for `checks` (by `check.code`).
- Add a unit test that builds a Suite with duplicate probe_ids
  and asserts `SuiteLogicError` is raised.

**Locked in by:** the unit test pins the contract; a
regression that drops the check fails it.

**Cross-references:** SuiteLogicError class definition in
`exceptions.py`; AP-04 (defensive validation at boundary).

---

### RA-03 Severity-override audit log

**Why:** `_apply_severity_override`
([`suite.py:174-187`](../../src/mgf/apiprobe/core/suite.py#L174)):

```python
def _apply_severity_override(self, finding):
    override = self.severity_overrides.get(finding.code)
    if override is None or override is finding.severity:
        return finding
    from dataclasses import replace
    return replace(finding, severity=override)
```

A consumer suite that demotes a `Severity.CRITICAL` finding to
`Severity.INFO` does so silently. The report consumer (a
human operator, a CI script) sees `Severity.INFO` and can't
tell whether:

- The Check originally emitted INFO (correct).
- A suite override promoted from INFO to INFO (no-op).
- A suite override demoted from CRITICAL to INFO (hidden
  policy decision).

DESIGN.md §3.2.2 explicitly acknowledges this as deferred to
v0.4. But for v1.0 the audit-trail is foundational —
"suite hides a critical finding" is the kind of pattern that
breaks audit trust.

**Concrete output:**

- When the override fires (severity actually changed), log
  at WARNING level via `_LOGGER`:
  ```python
  _LOGGER.warning(
      "severity override: code=%s original=%s overridden=%s",
      finding.code, finding.severity.value, override.value,
  )
  ```
- Optionally: store the original severity on the Finding
  itself (a new field `severity_original: Severity | None`)
  so the JSON report carries it. Mark the field as
  experimental.
- Add a test: build a suite with a CRITICAL→INFO override;
  assert the log line + (optionally) the `severity_original`
  field.

**Locked in by:** the unit test exercises the path.

**Cross-references:** DESIGN.md §3.2.2; **LG-04** structured
audit-event field convention.

---

### RA-04 Cookie value sanitization

**Why:** `HttpxTransport.send`
([`httpx_transport.py:94-104`](../../src/mgf/apiprobe/transport/httpx_transport.py#L94)):

```python
request_cookies: dict[str, str] = {}
...
if probe.auth is not None:
    creds = probe.auth.prepare()
    request_cookies.update(dict(creds.cookies))
```

Operator-supplied probe config flows: `creds.cookies` → dict →
httpx. If the operator's probe YAML/Python contains a cookie
value with `\r\n` (e.g., a value pasted from a security-test
fixture), httpx ≥ 0.27 will reject; older versions may pass
it through.

For a VERIFICATION HARNESS the operator usually controls the
input so the attack surface is small. But:

- The probe config can come from a security-test author who
  is deliberately probing for header-injection.
- The CookieAuth flow reads from env vars; an env var leaked
  with weird content reaches the cookie unsanitized.

Defence-in-depth: validate at the AuthCredentials → header
boundary.

**Concrete output:**

- A `_validate_cookie_value(value: str) -> None` helper that
  rejects CR/LF/NUL.
- Call on every cookie value in `request_cookies` before
  passing to httpx.
- On rejection: raise `TransportError(url=..., cause="cookie
  value contains invalid characters")`.
- Same pattern as mgf-http RA-03; share the helper between
  the two siblings via a follow-up extraction if both close.

**Locked in by:** unit test sending a `\r\n`-containing
cookie via a custom AuthFlow; assert TransportError.

**Cross-references:** mgf-http RA-03 (same input-validation
pattern at the transport boundary); SC-09.

---

### RA-05 `follow_redirects=True` in API verification

**Why:** `HttpxTransport.__init__`
([`httpx_transport.py:60-68`](../../src/mgf/apiprobe/transport/httpx_transport.py#L60))
sets `follow_redirects=True`. For an HTTP CLIENT this is
usually the right default (provider → CDN, http → https
upgrade). For a VERIFICATION HARNESS this can mask the real
issue:

- Operator writes a probe for `GET /api/v1/users`.
- The provider deprecated v1; it now returns 301 to
  `/api/v2/users`.
- httpx follows the redirect.
- The probe sees the v2 response.
- The probe's `expects_json_shape({...})` was written for v1.
- Check fires → operator thinks v2 has a bug → wastes time
  diagnosing.

Reality: v1 is gone; the probe was verifying the wrong thing.

A verification harness SHOULD surface redirects as findings,
not silently follow them.

**Concrete output:**

- Change `HttpxTransport.__init__` default to
  `follow_redirects=False`.
- Add a `RedirectFollowed` check (or a `RedirectSurprise` check
  per `checks/observability.py` style) that fires when the
  response is a 3xx.
- Add a per-probe opt-in (`probe.follow_redirects: bool = False`)
  for the rare case where the probe explicitly tests redirect
  behaviour.
- This is a **MINOR-breaking change** for v0.x but
  philosophically right. Document in the cutover guide.
- Add tests: 302 response with default settings produces a
  `redirect-followed`-style finding; same response with
  `probe.follow_redirects=True` follows + verifies the
  target.

**Locked in by:** the unit tests; the cutover guide pins the
behaviour change.

**Cross-references:** SCOPE.md §SP-AP-* policy on
verification-shape (this is a behaviour-shape change worth
codifying explicitly).

---

### RA-06 httpx client pool reuse across suites

**Why:** `HttpxTransport` holds one `httpx.AsyncClient`
([`httpx_transport.py:64-69`](../../src/mgf/apiprobe/transport/httpx_transport.py#L64)).
Reusing the transport across `Suite.run()` calls reuses the
connection pool — good for throughput but introduces a few
edge cases:

- A long-running operator session running periodic suite
  probes against MANY hosts grows the connection pool
  unboundedly. httpx's default pool size is 100; once
  exceeded, new connections wait.
- Two suites with conflicting TLS-verification policies
  (one expects strict verify, one doesn't) can't share a
  transport — but the transport doesn't surface this; the
  second suite silently uses the first's verify_tls
  setting.
- TLS session resumption across suites means a leaked
  intermediate cert affects every suite run after the first.

For v0.1 these are mostly theoretical. Worth tracking before
they bite a real consumer.

**Concrete output:**

- Two options:
  1. **Document the constraint.** Add to docstring:
     "HttpxTransport is intended for one-suite-per-transport
     usage in long-running contexts. For a long-running
     operator session probing many providers, construct a
     new transport per suite (or per host)."
  2. **Add a connection-pool size kwarg.** `HttpxTransport(...,
     max_connections=100)` exposed as a setting. Bound the
     pool growth.
- Likely both. The doc fix is XS; the kwarg is S.
- Test: build many transports concurrently; assert reasonable
  resource usage.

**Locked in by:** the docstring + (optional) the bound-test.

**Cross-references:** PC tracker in mgf-common (performance
+ capacity items — sustained-throughput vs cold-start
trade-offs).

---

### RA-07 Empty credential treated as unset

**Why:** `_resolve_credential`
([`auth/flows.py:41-46`](../../src/mgf/apiprobe/auth/flows.py#L41)):

```python
if value is None or value == "":
    raise AuthError(
        flow_name=flow_name,
        reason=f"environment variable {env!r} is unset or empty",
    )
```

Empty string is treated as unset. The error message
acknowledges both cases ("unset or empty") but the
behaviour is identical.

Some auth flows use intentionally-empty values:

- **Test-mode bearers.** Some test fixtures expect an empty
  bearer header (`Authorization: Bearer `) to verify the
  endpoint's empty-token handling.
- **Anonymous-tier API keys.** A few providers (rare) expect
  the API key header present but value empty for the
  anonymous tier.
- **Operator-disabled probes.** `MYTOKEN=""` to temporarily
  disable a probe without removing the env var entirely
  (operator habit).

These are edge cases but treating them as `AuthError`
prevents the legitimate use of empty values.

**Concrete output:**

- Split the check:
  - `value is None` → "environment variable is unset"
  - `value == ""` → distinct case; offer a kwarg
    `allow_empty: bool = False` on the flow constructors;
    when True, empty value is preserved.
- Optionally: emit a WARNING audit log when `allow_empty=True`
  fires (operator awareness).
- Add tests: `allow_empty=False` (default) still raises;
  `allow_empty=True` returns empty string.

**Locked in by:** the unit tests cover both branches.

**Cross-references:** EH-09 (actionable hints — the original
"unset or empty" message is OK but can split into two
distinct errors).

---

## §5 Closed items

- **RA-01** — Defensive failure isolation. Wrapped
  `_run_one_probe` inside `Suite.run`'s `_execute` closure with
  a try/except over `Exception`: any uncaught exception in a
  check or transport now produces a synthetic
  `suite.probe.exception` finding (CRITICAL,
  `RootCause.SUITE_LOGIC`) instead of cancelling the whole
  gather. Sibling probes run to completion; the operator sees
  every probe's findings plus the synthetic finding pointing at
  the failing one. Switched `asyncio.gather` to
  `return_exceptions=True` as belt-and-braces — if a future
  refactor drops the inner wrap, the gather still doesn't lose
  results; the per-result loop builds the same synthetic
  finding for any escaped exception. The remediation text on
  the synthetic finding points at the WARNING log (with
  `exc_info=True`) for the traceback. (2026-05-17, commit
  pending.)
- **RA-02** — Probe-id + check-code uniqueness enforced at
  suite-build time. Added `_assert_unique_probe_ids` and
  `_assert_unique_check_codes` helpers called from
  `Suite.__init__`; either raises `SuiteLogicError` with a
  message that names the offending identifier and explains
  why the collision matters (reports key findings by
  `probe_id`; `severity_overrides` index by `code`). Probes
  with `probe_id=None` are skipped (the Suite auto-generates
  a fallback id at run time, so None isn't a collision the
  operator controls). `SuiteLogicError` was already in
  `exceptions.py` per the PUBLIC_API.md docs — this finally
  raises it. (2026-05-17, commit pending.)
- **RA-03** — Severity-override audit log. Every applied
  override (when the override actually changes the severity)
  emits a WARNING log line with `audit=True` extra (matching
  mgf-common's LG-04 audit-event convention). Extra fields
  carry `event="mgf_apiprobe.severity_override"`,
  `finding_code`, `severity_original`, `severity_overridden`,
  `probe_id`. A suite that demotes CRITICAL → INFO leaves a
  paper trail even though the report itself carries the
  demoted severity. Sanity test pins that no-op overrides
  (same severity → same severity) don't emit the log —
  operators don't see noise on every finding. DESIGN.md
  §3.2.2 deferred this to v0.4; the audit-trail need is
  v1.0-foundational so it ships now. (2026-05-17, commit
  pending.)
- **RA-04** — Cookie value sanitization (CR/LF). Already
  shipped: `_assert_no_crlf_in_cookies(request_cookies, url=url)`
  is called in `httpx_transport.py` before every send (line 115);
  on CR/LF in any value the transport raises `TransportError`
  with an actionable cause string. Backed by
  `test_cookie_value_with_crlf_raises_transport_error` in
  `tests/unit/transport/test_httpx_transport.py`. Tracker entry
  was stale — the work landed in an earlier pass and was never
  flipped. (2026-05-17, P2 sweep — verification close.)

---

## §6 Notes on methodology

This first pass sampled the load-bearing files (~1800 LOC
of the ~5000 total) end-to-end against:

- **RA** rule patterns from mgf-common's
  `inprogress/RELIABILITY_AND_ACCURACY.md`.
- **EH** rules from `mgf-standard/docs/standards/ERROR_HANDLING.md`
  — especially **EH-04** top-level handlers, **EH-10**
  best-effort observers, **§11.2** `gather(return_exceptions=True)`
  discipline.
- **SC** rules from `mgf-standard/docs/standards/SECURITY_STANDARD.md`
  — input validation at boundaries, secret handling, traceback
  scrubbing.
- **LG** rules from `mgf-standard/docs/standards/LOGGING.md` —
  structured audit-event fields, redaction.
- The project's own [`DESIGN.md`](../../DESIGN.md) and
  [`docs/standards/SCOPE.md`](../standards/SCOPE.md) — items
  the design explicitly defers (e.g., severity-override
  audit logging) become P1 candidates for v1.0.

The audit method:

1. Read the load-bearing source files end-to-end.
2. Spot-check the matchers, checks, and CLI for the same
   patterns.
3. For every concern surfaced, verify `file:line` against the
   live source.
4. Cross-reference against the cornerstone's RA tracker and
   sister-sibling trackers (mgf-http for transport-layer
   parallels).
5. Triage: items that don't tie to a rule + concrete evidence
   are observations.

Seven items + seven invariants. The project is bigger than
most siblings; future passes should look for:

- **Per-check robustness.** Each check in `checks/` has its
  own edge cases (regex robustness in `schema.py`, JSON
  parse failure in `contract.py`). A check-by-check audit
  pass would find more items.
- **Matcher correctness.** The matcher DSL
  (`core/matchers/*.py`) is a tested primitive but property-
  testing it more aggressively would catch composition
  bugs.
- **CLI shape.** `cli/run.py` / `cli/doctor.py` / `cli/checks.py`
  are operator-facing; their error-message shapes matter
  per **EH-09** actionable hints.
- **Pattern parity with the cornerstone.** When mgf-common
  closes a systemic invariant, check whether this sibling
  needs the same shape (e.g., RA-01 here is a sibling-scoped
  version of mgf-common's RA-02 rollback chain).

When an item closes, move it to §5 with the closing-commit
SHA.
