# Magogi Foundation Standards — Conformance Tracker (mgf-sqlalchemy)

> **Status.** v0.1 — initial audit. Created 2026-05-18 per v2.8
> standards bump (DOC-15 + CFM-01..04).
> **Scope.** mgf-sqlalchemy's conformance to the standards at
> [mgf-standard/docs/standards/](https://codeberg.org/magogi-admin/mgf_common/src/branch/main/docs/standards/)
> (current standards version: v2.8).
> **Audience.** Maintainer-tomorrow, AI coding agents, future
> contributors.
> **Cross-references.**
> [README.md](../../README.md) (declared level),
> [CHANGELOG.md](../../CHANGELOG.md) (release history).

---

## §1 You are here

**Project shape:** Async-SQLAlchemy helpers — engine/sessionmaker factories, tenant_session.

**Current version:** 0.5.7.

**Declared TARGET conformance level: L2** (per CFM-02). **Current VERIFIED standing (2026-06-07 depth audit): below L2** — declared, not met (but the strongest of the audited siblings so far).

Of the **218** current MUSTs: **115 ✅ verified** (file:line, refute-survived) · **2 ⏳ open MUST gaps** · **100 N/A** (library shape — adapts SQLAlchemy, no GUI/deploy/standalone-service) · **0 declined** (2 auditor-🚫 reclassified ⏳ — unmet, not declines). Applicable (non-N/A) = **118**; **115/118 (97%) evidenced** — the code-quality families (DP all ✅, EH/LG/SC largely ✅) hold; the gaps are library-hygiene (CI publish, SCOPE policy, PUBLIC_API.json) + a few CONFIGURATION/ERROR_HANDLING specifics. CFM-02 **L2 requires every MUST**, so the prior unset "(set on first depth audit)" estimate is now replaced by evidence.

**Open-gap clusters (the 33 ⏳ — detail in §Z):**

| Cluster | Rules | Count |
|---|---|---|
| CI publish pipeline (no tag-driven chain) | REL-06, REL-08, WF-02, WF-03, WF-05, WF-06, WF-07, WF-08, WF-11 | 9 |
| SCOPE policy absent (SP-01..06) | SP-01, SP-02, SP-03, SP-04, SP-05, SP-06 | 6 |
| API / docs surface (PUBLIC_API.json, version-sync, drift, propagation, pypi.org) | AP-13, AP-14, DOC-03, DOC-08, DOC-09, DOC-18, PKG-12 | 7 |
| CONFIGURATION specifics | CF-05, CF-08, CF-10 | 3 |
| ERROR_HANDLING specifics | EH-07, EH-09 | 2 |
| misc (corpus-pin, presentation, smoke-tier, perf-attr, lightweight tag) | AG-16, PR-01, PR-07, REL-01, TS-21, TS-28 | 6 |

**2026-06-07 depth audit provenance.** 16-family auditor fan-out + adversarial refute on every ✅ (~30 agents, hardened "do-not-read-the-scaffold" prompt; two truncated families [RELEASING, DOCUMENTATION] re-filled by a 10-id micro-audit). Two auditor-🚫 verdicts (AP-13 no `__version__`/sync, PKG-12 residual pypi.org) reclassified ⏳ — unmet, not deliberate CFM-04 declines. Per-rule verdicts with file:line are in §Z; this supersedes the unset 2026-05-18 initial-audit placeholders + consolidates the duplicate §Z/§6 enumeration.


## §2 Per-standard audit

Audit method: cross-reference the per-rule list in each standard
under [mgf-standard/docs/standards/](https://codeberg.org/magogi-admin/mgf_common/src/branch/main/docs/standards/)
against this sibling's source tree + tests + docs.

Status markers (CFM-03):
- **✅** conformant — implementation + tests + docs match the rule.
- **🚫** declined-with-rationale — rule doesn't apply OR was
  deliberately not adopted; rationale in §3 (CFM-04).
- **⏳** in-progress — adoption planned; gap documented elsewhere.
- **N/A** — rule premise doesn't apply to this project's shape.

### §2.1 DP — DESIGN_PRINCIPLES

(initial audit: ✅ structurally; depth pass on first standards-bump trigger)

### §2.2 EH — ERROR_HANDLING

(initial audit: ✅ structurally; depth pass on first standards-bump trigger)

### §2.3 LG — LOGGING

(initial audit: ✅ structurally; depth pass on first standards-bump trigger)

### §2.4 SC — SECURITY_STANDARD

(initial audit: ✅ structurally; depth pass on first standards-bump trigger)

### §2.5 CF — CONFIGURATION

(initial audit: ✅ structurally; depth pass on first standards-bump trigger)

### §2.6 AP — API_DESIGN

(initial audit: ✅ structurally; depth pass on first standards-bump trigger)

### §2.7 TS — TESTING

(initial audit: ✅ structurally; depth pass on first standards-bump trigger)

### §2.8 DOC — DOCUMENTATION

(initial audit: ✅ structurally; depth pass on first standards-bump trigger; v2.8 DOC-13/14/15 newly applicable)

### §2.9 REL — RELEASING

(initial audit: ✅ structurally; depth pass on first standards-bump trigger)

---

## §3 Decline-with-rationale ledger (CFM-04)

| AP-14 | API_DESIGN | import-linter enforcement of 'consumer fixtures only public' | No in-repo consumer harness to lint; library's own tests white-box `_` modules by design. Closed-box mechanism (private `_` + complete `__all__`/PUBLIC_API.md + TS-21 public-surface smoke) satisfies the intent. Revisit if an in-repo consumer-smoke harness is added. | 2026-06-07 |

(none yet — initial audit. Populate as deferrals get filed,
each carrying a rationale per
[principles/non-adoption-is-valid.md](https://codeberg.org/magogi-admin/mgf_common/src/branch/main/docs/standards/principles/non-adoption-is-valid.md).)

---

## §4 Audit log

| 2026-06-07 | depth audit (16-family fan-out + adversarial refute; ~30 agents + 10-id micro-audit) | first evidence-based per-MUST audit | **85 ✅ / 33 ⏳ / 100 N/A** of 218 (72% of applicable); declared L2 → below-L2 (strongest sibling audited). Clusters: CI publish (WF/REL), SCOPE (SP-01..06), API/docs (PUBLIC_API.json/AP-13/DOC-08/09/18/PKG-12), CF (3), EH (2). Audit only — no code changed. |

| Date | Auditor | Trigger | Findings |
|---|---|---|---|
| 2026-05-18 | initial audit (v2.8 standards bump) | DOC-15 + CFM-01..04 introduction; this tracker created | scaffolded; first depth audit to follow |

---

## §5 Cross-references

- [mgf-standard/docs/standards/](https://codeberg.org/magogi-admin/mgf_common/src/branch/main/docs/standards/)
  — the standards source-of-truth.
- [`docs/inprogress/RELIABILITY_AND_ACCURACY.md`](RELIABILITY_AND_ACCURACY.md)
  — falsifiable per-rule evidence on the RA-* surface
  (where applicable).
- [`docs/inprogress/SECURITY_HARDENING.md`](SECURITY_HARDENING.md)
  — falsifiable per-rule evidence on the SC-* surface.
- [`docs/inprogress/PERFORMANCE_AND_CAPACITY.md`](PERFORMANCE_AND_CAPACITY.md)
  — falsifiable per-rule evidence on the perf-shape surface.
- [`../../FEEDBACK.md`](../../FEEDBACK.md) — papers filed
  against this sibling.
- [mgf-standard/docs/standards/principles/non-adoption-is-valid.md](https://codeberg.org/magogi-admin/mgf_common/src/branch/main/docs/standards/principles/non-adoption-is-valid.md)
  — ASPIRE-04 / CFM-04 documented-non-adoption principle.
- [Template this file was scaffolded from](https://codeberg.org/magogi-admin/mgf_common/src/branch/main/docs/recipes/mgf-standards-conformance-md-template.md).

---

---

## §Z Per-MUST evidenced audit (all 259 MUSTs (PAPER-100 re-baseline 2026-06-11) — CFM-03 completeness)

> **2026-06-07 depth audit** (16-family fan-out + adversarial refute on every ✅; ~30 agents, hardened no-scaffold prompt + a 10-id micro-audit for two truncated families). Each ✅ cites file:line and survived refutation. **Mix: 85 ✅ · 33 ⏳ · 100 N/A · 0 🚫** (2 auditor-🚫 — AP-13, PKG-12 — reclassified ⏳: they are unmet, not CFM-04 declines). Replaces the prior duplicate ⏳ scaffold (§Z + §6).


### DESIGN_PRINCIPLES

| Rule | Status | Evidence | Notes |
|---|---|---|---|
| DP-01 | ✅ | Library has no UI/core split and no entry points; src/mgf/sqlalchemy/ is 5 flat private modules re-exported via __init__.py. No third-party SDK is hidden behind a provider here (SQLAlchemy i | DP-01 (layering MUST be enforced; UI MUST NOT be imported by core; CI lints) is satisfied vacuously-but-correctly for this adapter shape: there is no UI layer and no provider-fronted SDK, so there is no downward-flow violation possible. The |
| DP-02 | N/A | No provider ABC, no providers/ package, no mock implementation, no EXPECTED_METHODS lock-in test. create_engine (_engine.py:166) calls create_async_engine directly; create_sessionmaker (_ses | DP-02 requires every third-party I/O dependency to sit behind an ABC with prod + mock impls. Per the carve-out and §14.2 (scope the rule to the shape it serves), SQLAlchemy is the FRAMEWORK this library adapts — not a swappable third-party  |
| DP-03 | ✅ | The library defines no cross-module domain types of its own to pass as identity — it adapts SQLAlchemy's own types (AsyncEngine, AsyncSession, async_sessionmaker) which it returns to the cal | DP-03 forbids bare strings/dicts crossing a module boundary AS IDENTITY and requires frozen domain types. This adapter ships no frozen-dataclass domain layer because it has no domain objects of its own — it returns framework objects and a U |
| DP-04 | ✅ | pyproject.toml:175-184 sets [tool.mypy] strict=true, disallow_untyped_defs=true, disallow_incomplete_defs=true, warn_return_any=true, packages=['mgf.sqlalchemy']; py.typed ships (src/mgf/sql | DP-04 (every public function type-annotated; mypy --strict passes on src/; no unjustified Any) is met: mypy strict is configured and CI-gated, and the Any usages are confined to **extra kwargs forwarded verbatim to SQLAlchemy and to the _ma |
| DP-05 | ✅ | tests/unit/ holds test_engine/test_session/test_mixins/test_pagination + two tenant_session files, mirroring src. Unit tests use 'sqlite+aiosqlite:///:memory:' (test_engine.py:13,20,43) and  | Refute attempt failed. The unit suite mirrors src, runs against in-memory sqlite + mocks, and has no production credentials, no network, and no real third-party daemon. The 'asyncpg' strings are URL literals/comments, not connections (grep- |
| DP-06 | ✅ | Security: _session.py:117-128 (SH-01) UUID-validation SQL-injection boundary, Hypothesis-backed (tests/unit/test_tenant_session_security.py exists); _engine.py:26-43 make_safe_url password m | Refute attempt failed. All four first-class concerns are visibly treated as design surface, each wired into the source with cited tracker IDs (SH-/RA-/PC-), backed by tests, and tracked in standing trackers. DP-06's 'every PR description MU |
| DP-07 | ✅ | Verified every public export in __all__ has an intent+invariant docstring: create_engine (_engine.py:78-124, with Performance/Notes section), make_safe_url (:27-39, states the SH-02 logging- | Refute attempt failed. Every public class/function carries a docstring stating intent and invariants — several go well beyond the bar (tenant_session spells out the SQL-injection boundary, the autobegin contract, and the NIL-UUID security c |
| DP-08 | ✅ | DP-08 is a SHOULD ('code SHOULD be replaceable') with a MUST that the swap recipe be documented near the component. The only swappable external is the DB driver. create_engine docstring (_en | Refute attempt failed. The swap mechanism (change the SQLAlchemy URL scheme; the rest is unchanged) is documented both in the component's own docstring and in the recipe doc near it, satisfying the MUST. For SQLAlchemy itself (the framework |
| DP-09 | N/A | grep for CancellationToken/cancel/threading.Event used as a global flag → none in src/. The library has no long-running operation it owns: create_engine/create_sessionmaker are synchronous f | DP-09 (long-running ops MUST take an explicit CancellationToken-like parameter; never a thread-global) applies to operations the component owns and runs for a long time. This adapter owns no such operation — every helper is a factory or a s |
| DP-10 | ✅ | The library has no keyring→file-style fallback backend to query/log. The one place a silent fallback could hide is the SQLite-vs-server pool-kwarg branch (_engine.py:146-149) — but that is a | DP-10 (no silent fallbacks; an active backend MUST be queryable, SHOULD be logged at startup) has no fallback-backend surface in this library, so its core clause is N/A — but the spirit (no silent degradation) is affirmatively upheld: every |
| DP-11 | ✅ | grep -rn 'create_task'/'TaskGroup' src/ → none (only @asynccontextmanager tenant_session and async signatures). pyproject.toml:133 selects the RUF family (which includes RUF006 unawaited-tas | Refute attempt failed. DP-11 ('every asyncio.create_task result MUST be retained') is satisfied vacuously — zero bare create_task calls — AND the mechanical guard is enabled (RUF006 ships inside the selected RUF family; ASYNC is selected ex |
| DP-12 | ✅ | _mixins.py:95 'from datetime import UTC, datetime'; :161 datetime.now(UTC) in uuid7; :299/:305 default/onupdate=lambda: datetime.now(UTC) on created_at/updated_at; :427 datetime.now(UTC) in  | Refute attempt failed. All datetime construction is tz-aware UTC, columns are DateTime(timezone=True), no naive datetime is produced anywhere in src/, and the DTZ lint family is selected and CI-enforced to keep it that way. Per DP-12 / TIME |
| DP-13 | ✅ | tenant_session is an @asynccontextmanager (_session.py:93): the GUC scoping is bounded by the caller's `async with` and SET LOCAL auto-resets on commit/rollback (:100-103). set_audit_user is | Refute attempt failed. Every resource this library itself acquires is released deterministically — the contextvar token via try/finally, the tenant GUC via the async context manager + transaction scope. The engine/session are factory output |

### ERROR_HANDLING

| Rule | Status | Evidence | Notes |
|---|---|---|---|
| EH-01 | N/A | src/mgf/sqlalchemy/{_engine,_session,_pagination,_mixins}.py — the only exceptions raised by this library are stdlib ValueError (_engine.py:158, _pagination.py:99, _session.py:78) and Runtim | EH-01 requires every exception raised by APPLICATION code to subclass the project base AppError. This is a thin SQLAlchemy adapter with no exceptions.py and no AppError subtree — it raises stdlib ValueError/RuntimeError for caller-misuse (c |
| EH-02 | N/A | No try/except translating a third-party exception exists. _engine.py:42 catches make_url() failures but returns a sentinel (not a translation). SQLAlchemy errors from session.execute (_sessi | EH-02 requires third-party exceptions to be translated to typed app exceptions at the boundary that owns the call. Per the carve-out brief, SQLAlchemy is the framework this library ADAPTS, not a third-party I/O SDK hidden behind a provider  |
| EH-03 | N/A | No `raise ... from ...` and no re-raise-of-translated-exception anywhere in src/. The three raises (_engine.py:158, _pagination.py:99, _session.py:231) are originating raises (caller-misuse  | EH-03 governs cause-chaining when RE-RAISING a TRANSLATED exception. This library performs no exception translation (see EH-02) and never re-raises a caught exception, so there is no site where `from e` is owed. The only broad except (make_ |
| EH-04 | N/A | No entry point: no CLI (no __main__, no console_scripts in pyproject), no process/thread/asyncio loop owned by this library. It is import-only — consumers call create_engine/create_sessionma | EH-04 (top-level handler at every entry point: CLI _run_and_translate_exceptions / sys.excepthook / threading.excepthook / loop.set_exception_handler) applies to processes/apps that OWN an entry point. This adapter library owns none — the c |
| EH-05 | N/A | No crash reporter, no state-dir crash JSON, no report_now call anywhere in src/. Library does not catch unhandled exceptions at a top level (see EH-04). | EH-05 (unhandled exceptions produce a local crash report + optional remote forward) is downstream of EH-04's top-level handler, which this library does not own. The consuming service's top-level handler (using mgf.common.observability.repor |
| EH-06 | N/A | No GUI, no QThread/CoreWorker, no PySide6/Qt dependency. pyproject runtime deps are sqlalchemy + mgf-common only. | EH-06 governs GUI worker threads (catch every exception, forward via error(str) signal). Per the carve-out brief PR-03/04/05 are N/A (no GUI). No GUI worker surface exists. N/A. |
| EH-07 | ✅ | Sole broad catch: src/mgf/sqlalchemy/_engine.py:40-43 `try: return make_url(url).render_as_string(hide_password=True) / except Exception: return "<malformed-url>"`. The except body LOGS NOTH | [verify-refuted: under the literal EH-07 carve-out text, make_safe_url fits NEITHER exemption. It is not carve-out (a) — there is no `finally:` and no `contextlib.suppress(...)`; it is a try/except returning a sentinel. It is not carve-out — FIXED 2026-06-07 (0.5.7): make_safe_url's `except Exception` narrowed to the typed `except ArgumentError` (what make_url raises on malformed/None URLs) — EH-07-compliant, never-raise intent preserved |
| EH-08 | N/A | No typed AppError subclass is defined or raised in src/. Raises are stdlib ValueError/RuntimeError carrying only formatted message strings (e.g. _engine.py:158, _pagination.py:99, _session.p | EH-08 (every TYPED exception carries machine-readable constructor fields, not just a message) governs the project's typed AppError subclasses. This library defines no typed exceptions — it raises stdlib errors for caller-misuse. There is no |
| EH-09 | ✅ | Every raised message ends with an actionable step (_engine.py:159-163 'Use the explicit parameter ...'; _session.py:79-83 same; _session.py:231-236 'Ensure SQLAlchemy autobegin is on, or wra | [verify-refuted: the message-content half of EH-09 holds (each raise ends in an actionable step), but EH-09 as written in §9 has a second MUST — every actionable suffix MUST be pinned by a substring test — and that half is unmet. The create — FIXED 2026-06-07: tests/unit/test_exception_hints.py pins the 4 actionable-hint substrings (engine/sessionmaker collisions, tenant transaction, pagination limit) |
| EH-10 | N/A | No best-effort observer fan-out. The closest constructs — _mixins.py:335-349 SQLAlchemy before_insert/before_update event listeners (_stamp_on_insert/_stamp_on_update) — contain NO try/excep | EH-10 (best-effort observers — hook executors, scheduler ticks, alert evaluators, libvirt callbacks — must catch broadly, log WARNING, return bool, continue) requires a fan-out observer surface. This library has none. The ORM event listener |
| EH-11 | N/A | No retry logic anywhere in src/. The only resilience knob is SQLAlchemy's own pool_pre_ping=True (_engine.py:46,72) which is a per-checkout liveness ping handled inside SQLAlchemy, not an ap | EH-11 (retries MUST use exponential backoff with full jitter + finite cap, configurable + observable) applies to code that performs retries. This adapter performs none — connection retry/recycle is delegated to SQLAlchemy's pool, which the  |
| EH-12 | N/A | No multi-attempt external write/send operation in src/. tenant_session emits a single SET LOCAL (_session.py:222); paginate_cursor is a pure in-memory slice (_pagination.py, no I/O, document | EH-12 (operations against external systems with multi-attempt cost MUST be idempotent) applies to retried writes/sends. This library issues no retried external writes — SET LOCAL is a single transaction-scoped statement the consumer drives, |
| EH-13 | N/A | No outbound call into an upstream that could be amplified — no circuit breaker, and none owed. The library opens DB connections lazily via SQLAlchemy's pool (_engine.py:104-106 'not yet conn | EH-13 (upstream-amplifying load MUST be bounded; circuit breaker canonical) applies to code that drives failing external calls in a way that can worsen an upstream outage. This adapter does not retry or fan out against the DB; the connectio |

### LOGGING

| Rule | Status | Evidence | Notes |
|---|---|---|---|
| LG-01 | N/A | grep for 'getLogger\|logging\.\|LOG' across src/mgf/sqlalchemy/*.py (5 modules) returns only the word 'logging' inside the make_safe_url docstring (_engine.py:27) and the noun 'event' in mix | LG-01 binds 'every module [that logs]' to acquire its logger via logging.getLogger(__name__). These are pure adapter modules (engine factory, sessionmaker, pagination, mixins) that emit zero log records — the rule's premise (a module that l |
| LG-02 | N/A | pyproject.toml has no [project.scripts]/console_scripts/GUI entry point (the only '__main__' hit is a coverage-exclude regex on line 246). __init__.py docstring confirms 'framework-agnostic: | LG-02 mandates configuring logging 'in exactly one place per entry point' (CLI main, GUI app.run, scheduler entry). A library with no entry point has no place to own logging setup — the consuming application owns it. Per the standard's own  |
| LG-03 | N/A | No log record is emitted anywhere in src/ (grep confirms zero LOG/getLogger call sites). trace_id/span_id attachment is the JsonFormatter's job (LOGGING.md §5.3), which lives in mgf.common.o | LG-03 requires every log RECORD to carry trace_id/span_id when a span is active, added automatically by the standard formatter. With no records emitted and no formatter installed by this library, there is no record to carry OTel context. Th |
| LG-04 | N/A | The library installs no formatter and emits no records, so there is no sink to redact before. It DOES ship make_safe_url (_engine.py:26-43), which masks an embedded DB password via make_url( | LG-04 binds the FORMATTER to redact sensitive fields before any sink sees them, with a configurable redaction set. The Redactor lives in mgf.common.observability and is wired by the consumer's setup_logging — this library runs no formatter/ |
| LG-05 | N/A | No ERROR-level log record exists in src/ — grep for '.exception(' / 'exc_info' over the source returns zero log call sites (only the noun 'event' and docstring 'logging'). Error paths raise  | LG-05 governs the shape of ERROR-level LOG records (must carry exc_info, not a stringified exception). The library surfaces failures by RAISING typed exceptions for the caller to handle/log, never by logging at ERROR itself. With no ERROR l |
| LG-06 | N/A | No log records and no entry point (pyproject.toml has no scripts). __init__.py documents this as a framework-agnostic sibling library that plugs into consumer seams. | LG-06 requires logs to REACH a searchable aggregator and forbids 'console only, no aggregation' in production. Aggregator wiring (rotating file / stdout / OTLP) is an entry-point/deployment concern owned by the consuming application's setup |
| LG-07 | N/A | No GUI: pyproject.toml has no PySide6/Qt/GUI entry point; __init__.py declares 'no FastAPI, no Starlette, no Django' and the project is an async-SQLAlchemy adapter library with no UI surface | LG-07 is explicitly scoped to kind 'gui-app' (per-kind matrix, LOGGING.md line 44). mgf-sqlalchemy is a library, not a desktop GUI app, so the log-viewer-dialog rule does not apply. |
| LG-08 | N/A | grep finds no LOG.info/LOG.warning/etc. call sites in any of the 5 source modules; there is no log message string at all (lazy %-style or f-string). The only f-strings present build SQL/exce | LG-08 mandates lazy %-style formatting for LOG MESSAGES. With no log messages emitted, there is no message-formatting style to evaluate. The premise (a log call with a message template) does not bind. |
| LG-09 | N/A | No log call exists, so no extra={...} usage or message-concatenation to assess (grep for 'extra=' over src returns only the prose noun 'extra' meaning **extra kwargs, not a logging extra). S | LG-09 requires structured fields be passed via extra={} on a log call. There are no log calls, so there is no structured-field surface to bind. Premise does not bind. |
| LG-10 | N/A | No headless service entry point: pyproject.toml has no console_scripts, no systemd unit, no daemon main. The library is imported into a consumer process; it does not run as a standalone serv | LG-10 is scoped to kind 'service' (per-kind matrix, line 45) and requires a JournalHandler/OS sink at the service's OWN entry point. This adapter library has no entry point and is not a service; the rule does not apply. |
| LG-11 | N/A | The library emits no operation start/end records (no LOG calls anywhere in src/). Boundary-crossing functions exist (tenant_session runs SET LOCAL, the engine factory creates connections) bu | LG-11 requires start/end INFO records with a stable 'operation' field for ≥100ms or boundary-crossing functions. The standard locates this at the consumer's L2 use case (the function the CLI/GUI invokes), wrapped in operation_span. mgf-sqla |
| LG-12 | N/A | No log emission occurs in src/ (zero LOG call sites), so there is no per-record cost to bound. Where the library touches hot paths it stays cheap and silent (paginate_cursor is a pure slice, | LG-12 bounds the cost of log EMISSION (≤100µs/record, heavy work in the handler). With no emission, there is nothing to measure. Premise does not bind. |
| LG-13 | N/A | No high-frequency log sites exist — the per-flush event listeners (_stamp_on_insert/_stamp_on_update, _mixins.py:335-346) and the pagination helper emit zero log records, so there is nothing | LG-13 requires rate-limiting/sampling at high-frequency LOG sites so a runaway condition doesn't flood sinks. The candidate hot paths here (per-flush listeners, inner pagination) log nothing, so there is no log flood to guard against. Premi |
| LG-14 | N/A | The library's correlation context — the audit user — IS propagated via contextvars.ContextVar, not thread-local or function args: _audit_user_var = contextvars.ContextVar('mgf_sqlalchemy_aud | LG-14 mandates that custom correlation context propagate through contextvars.ContextVar (which the library does correctly, line 218) and that the standard formatter promote registered contextvars to log fields (a formatter concern that live |
| LG-15 | N/A | No INFO+ log records are emitted (zero LOG sites in src/), so there is no 'event' field to require, and docs/reference/EVENTS.md does not exist (ls of docs/reference returns nothing). The li | LG-15 requires every notable INFO+ log record to carry a stable <subject>.<action> 'event' field cataloged in EVENTS.md. With no log records emitted by the library, there is no record on which an event field is required and no event names t |
| LG-16 | N/A | No WARNING/ERROR log records exist in src/ (grep for LOG.warning/LOG.error/.exception returns zero). Failure conditions are surfaced as exceptions whose MESSAGES already carry what/why/how i | LG-16's MUST binds WARNING and ERROR LOG records specifically (it says so explicitly: 'why LG-16 is a MUST at WARNING+'). The library produces no such records, so the rule has no log site to bind. Its sibling EH-09 (the same what/why/how di |
| LG-17 | N/A | No ERROR log records are emitted (zero .exception/exc_info sites in src/), so there is no record on which to set a stable 'fingerprint'. Errors are raised as typed exceptions (ValueError/Run | LG-17 is itself a SHOULD (LOGGING.md line 458: 'LG-17 is a SHOULD (not a MUST)'), and its subject is the ERROR LOG record's fingerprint field, computed by the standard formatter from exc_info. With no ERROR records and no formatter run here |

### CONFIGURATION

| Rule | Status | Evidence | Notes |
|---|---|---|---|
| CF-01 | N/A | grep -rnE 'Settings\|load_settings\|os.environ\|getenv' src/ returns NOTHING; no pyproject/yaml config schema owned by the lib; __init__.py docstring states helpers take engine/sessionmaker/ | CF-01 is scoped 'consumer-owned-config'. mgf-sqlalchemy owns no config schema — it is a thin async-SQLAlchemy adapter whose runtime objects are produced by factory functions taking explicit args. There is no module here that reads env vars  |
| CF-02 | N/A | No Settings/BaseSettings class anywhere in src/; create_engine(database_url,...) / create_sessionmaker(engine,...) receive all inputs by argument (_engine.py:68, _session.py:42). No layered  | CF-02 (precedence) is scoped 'all' but presupposes a config object with layered sources. This library has none — the consumer owns precedence/loading and passes the resolved URL/engine down. There is no precedence chain to implement here, s |
| CF-03 | N/A | No config schema, no version field, no load path; grep finds no Settings class in src/. | CF-03 (schema version + migration) is scoped 'consumer-owned-config'. With no owned config schema, there is nothing to version or migrate. N/A. |
| CF-04 | N/A | No on-disk config writes; grep for write_text/atomic/save_settings in src/ returns nothing; the lib persists no state file. | CF-04 (atomic write, 0o600, lazy path expansion) is scoped 'consumer-owned-config'. The library never writes a config or state file, so there is no write to make atomic and no path default to expand lazily. N/A. |
| CF-05 | ✅ | No config file exists. grep -rniE 'password\|secret\|token' src/ finds only stdlib `secrets`/`secrets.token_bytes` (_mixins.py:91,165, uuid7 randomness) and a contextvar `token` reset (_mixi | CF-05 is scoped 'all': secrets must not live in a config file and must not leak. Verified: no config file, no stored secret, and the one credential surface (password embedded in a consumer-passed SQLAlchemy URL) is explicitly masked for the — RECONCILED 2026-06-07 ✅: audit rationale itself states 'no config file, no stored secret, the URL password is masked — the rule's intent is met. Upheld' (mislabeled ⏳) |
| CF-06 | N/A | No config schema / no YAML loader in src/; nothing parses an on-disk config to reject unknown keys. | CF-06 (unknown-key reject) is scoped 'consumer-owned-config'. No owned config file is parsed here, so there is no key namespace to validate. N/A. |
| CF-07 | N/A | No sub-config / satellite files (hooks/schedules/profiles) exist in the repo; the lib defines no satellite loaders. | CF-07 (sub-config files follow the same shape) is scoped 'consumer-owned-config'. The library ships no satellite config files. N/A. |
| CF-08 | ✅ | grep -rnE 'Settings\|load_settings' src/ returns NONE — no module-global Settings() singleton. Runtime objects come from factory functions taking inputs as parameters: create_engine(database | CF-08 is scoped 'all': no module-global config singletons; inject dependencies by argument. Verified: every helper receives its deps (URL, engine, session, tenant) explicitly; there is no forbidden module-global Settings. The 'load once at — RECONCILED 2026-06-07 ✅: audit rationale states 'every helper receives its deps explicitly; no module-global Settings — the injection discipline is met' (mislabeled ⏳) |
| CF-09 | N/A | No CLI/entry point in the package; it is a library (no __main__, no click group); pyproject defines no console_scripts. | CF-09 (--config flag + XDG default path) is scoped 'consumer-owned-config' and presupposes a CLI entry point. This is a pure library with no CLI surface. N/A. |
| CF-10 | ✅ | Unit tests construct objects with explicit literals: tests/unit/test_session.py:28+ use create_engine('sqlite+aiosqlite:///:memory:') and create_sessionmaker(engine, expire_on_commit=True);  | CF-10 is scoped 'all': tests use explicit values, no env-var leakage. There is no Settings class, but the analogous surface (engine/sessionmaker factories) is exercised entirely with hermetic literals (in-memory SQLite, tmp_path). The only — RECONCILED 2026-06-07 ✅: audit rationale states 'exercised entirely with hermetic literals (in-memory SQLite, tmp_path), no env-var leakage' (mislabeled ⏳) |
| CF-11 | N/A | No config schema / pydantic Field aliases in src/; nothing reads an on-disk config whose field could be renamed. | CF-11 (rename via Field alias + deprecation warning) is scoped 'consumer-owned-config'. With no owned config schema, there is no config field to rename without breaking on-disk files. N/A. |
| CF-12 | N/A | No config-modelled backend variants; the SQLite-vs-pooled-driver branch in create_engine (_engine.py:146-149) keys off the consumer-supplied URL prefix at call time, not a discriminated-unio | CF-12 (mutually-exclusive backend variants modelled as a discriminated union with a `kind` discriminator) is scoped 'all' but applies only where the consumer has such variants in its config. This library has no config model and no `kind`-di |

### SECURITY_STANDARD

| Rule | Status | Evidence | Notes |
|---|---|---|---|
| SC-01 | ✅ | .woodpecker.yml:73-76 secret-scan step runs `gitleaks detect --source . --no-banner --redact` on the pinned image zricethezav/gitleaks:v8.30.1, gated by `when: [push, pull_request, manual]`  | UPHELD. The library holds no secrets of its own — consumers supply the DB URL. The single secret-bearing surface (a connection URL with an embedded password) has a dedicated masking helper (`make_safe_url`) explicitly designed for log/error |
| SC-02 | N/A | No subprocess usage in the library. grep over src/ finds no `subprocess`, `shell=True`, `os.system`, or `shlex`. The package is a pure async-SQLAlchemy adapter with no shell/process surface. | N/A — the library invokes no subprocesses and accepts no user-supplied command templates. SC-02's argv-only/shell=False rule has no applicable call site. |
| SC-03 | N/A | No YAML/JSON/pickle deserialization in src/. grep finds no `yaml`, `pickle`, or untrusted-load surface; the library only constructs SQLAlchemy engines/sessions and slices in-memory row seque | N/A — the library deserializes nothing from an untrusted source. No YAML loader, no pickle, no JSON-from-network surface exists in the adapter. |
| SC-04 | N/A | The library performs no file writes — it builds engines/sessionmakers and a pure pagination function. No config.yaml, vault, crash report, or log-file writing surface in src/. | N/A — no on-disk private-data writes occur in this adapter, so the 0o600/atomic-write MUST has no applicable call site. |
| SC-05 | ✅ | _mixins.py:91 `import secrets`; line 165 `rand_bytes = secrets.token_bytes(10)` supplies the 10-byte random tail of the UUID-v7 generator (assembled at lines 166-172). grep over src/ for `ra | UPHELD. The sole cryptographic-adjacent surface (UUID-v7 random tail) uses the CSPRNG `secrets.token_bytes`, not the Mersenne-Twister `random` module. No weak hashes, no DIY crypto. Refutation attempt failed: the only `random`/`md5`/`sha1`  |
| SC-06 | N/A | The library makes no outbound TLS/HTTP/SSH connection of its own; consumers supply the DB URL and async driver. grep finds no `verify=False`, `CERT_NONE`, or `AutoAddPolicy`. DB-driver TLS i | N/A — no outbound connection is initiated by the adapter; TLS posture is delegated to the consumer-supplied driver/URL. The MUST has no applicable call site here. |
| SC-07 | N/A | The library opens no external request itself — `create_engine` returns an unconnected engine (lazy connect on first consumer use, per _engine.py:104-106). Connection/statement timeouts are d | N/A — the factory issues no external call; it hands back an engine the consumer drives. There is no 'blocks-forever path through a boundary' owned by this library. (Borderline: a stricter reading could push a default statement_timeout, but  |
| SC-08 | ✅ | _session.py:211-218 validates `tenant_id` via `UUID(tenant_id)` (raises ValueError on malformed input) BEFORE building any SQL string; the canonical `str(validated)` is then interpolated at  | UPHELD. Every untrusted input that reaches SQL or engine construction is typed/shape-validated at the function boundary exactly as SC-08 requires, and the ordering invariant (validate before any SQL is emitted) is regression-pinned by an ad |
| SC-09 | N/A | The library defines no log formatter and holds no Redactor — it consumes mgf-common's observability rather than owning a log sink. The one secret-adjacent value (URL password) is masked by ` | N/A — formatter-side field redaction (SC-09) is owned by mgf-common's logging pipeline, not by this adapter. The library installs no formatter, so the redactor MUST has no applicable surface here. |
| SC-10 | ✅ | `git ls-files uv.lock` → `uv.lock` (tracked); file present at 237221 bytes (Jun 4). .woodpecker.yml:63-69 `vuln-scan` step runs `pip-audit --strict` on the pinned python:3.12-slim image, gat | UPHELD. Both MUST clauses of SC-10 are met: a committed, git-tracked lockfile (uv.lock) and a CI vulnerability scanner (pip-audit --strict) gating every PR. Refutation attempt failed: the lockfile is confirmed tracked, and the scan step's ` |
| SC-11 | ✅ | _engine.py:40-43 `make_safe_url` returns the literal `"<malformed-url>"` on parse failure (the `except Exception` branch) rather than re-raising with the raw URL, and on success renders with | UPHELD. The library raises no exception that embeds secret material, and the one secret-bearing value (URL password) has an explicit scrubbing seam (`make_safe_url`) that fails closed to a literal placeholder on parse error rather than leak |
| SC-12 | ✅ | SECURITY.md exists at repo root (4698 bytes). Contains: a 'Supported versions' table (`0.2.x` supported / `0.1.x` not), a 'Reporting a vulnerability' section (Email bassam@magogi.org + Codeb | UPHELD. Root SECURITY.md is present and contains every element the SC-12 template requires: supported versions, security contact (email + private advisory channel), embargo expectations, and a disclosure-timeline table. Note (content-accura |
| SC-13 | N/A | The library stores no cryptographic keys at rest — its only crypto use is `secrets.token_bytes(10)` for ephemeral UUID-v7 generation (_mixins.py:165), which is not a persisted key. No embedd | N/A — no key-at-rest exists in this adapter, so the KDF/keyring storage MUST has no applicable surface. |
| SC-14 | N/A | The library performs no authentication of users/credentials — it sets a Postgres RLS tenant GUC for an already-authenticated session. There is no login boundary, no password/key verification | N/A — no authentication boundary exists in this adapter; the anti-enumeration/rate-limit MUST has no applicable call site. |
| SC-15 | N/A | The library constructs no filesystem path from external input. The only path-shaped value is the database_url string handed to SQLAlchemy (_engine.py:68), which is a connection URL parsed by | N/A — no external-input-derived filesystem path is constructed; the directory-traversal MUST has no applicable surface in this adapter. |
| SC-16 | N/A | No privileged operations — grep finds no `sudo`/`setuid`/`chmod`/capability/`--privileged` surface. The library is an in-process async-SQLAlchemy adapter with no OS-privilege escalation. | N/A — the adapter performs no privileged operation, so the minimum-privilege documentation MUST has no applicable call site. |
| SC-17 | N/A | The library emits no audit log records. It performs none of the SC-17 audit-triggering actions (vault read/write, subprocess, SSH, config write, key rotation, auth attempt) — its security-re | N/A — none of the SC-17 enumerated audit-triggering actions occur in this adapter, and it owns no logging surface. The audit-record MUST has no applicable trigger here. (The tenant-scoping action is arguably security-relevant, but the stand |
| SC-18 | ✅ | pyproject.toml:2-3 declares name `mgf-sqlalchemy` / version `0.5.5`; [build-system] (lines 99-101) declares `requires = ["hatchling>=1.21"]` + `build-backend = "hatchling.build"`. Runtime de | UPHELD. A pure-Python project (py3-none-any wheel) with a declared hatchling build backend, declared dependencies, and a committed lockfile is reproducible from a tagged source commit using only declared deps. SC-18's binary-wheel build-met |

### TESTING

| Rule | Status | Evidence | Notes |
|---|---|---|---|
| TS-01 | N/A | Not in the challenge set; not adjudicated in this refute pass. | Out of scope for this adversarial pass (only the 28 listed ✅ claims were challenged). |
| TS-02 | ✅ | Default suite ran 116 passed, 2 skipped with NO Postgres reachable (.venv pytest --cov). Unit tests use 'sqlite+aiosqlite:///:memory:' (test_engine.py:13,43; test_session.py:155). tenant_ses | Upheld. Verified empirically: the default invocation is hermetic (no creds/network/daemon) and the real-Postgres test is layer-marked + skip-gated so it never runs by default. [verify-upheld] |
| TS-03 | ✅ | Full default suite passed clean under filterwarnings=['error'] (95.03% cov, 116 passed). set_audit_user contextvar always unbinds (test_mixins.py:223-241 test_bind_and_unbind/test_nested_bin | Upheld. The only process-global state touched (contextvar, engine pools) is restored/disposed via fixtures; suite is green under warning-escalation. [verify-upheld] |
| TS-04 | ✅ | pyproject.toml [tool.pytest.ini_options] filterwarnings = ['error']. audit_engine/soft_engine teardowns (test_mixins.py:129-133, :266-267) cite the escalation as load-bearing. Suite ran gree | Upheld. Literal MUST met and demonstrably load-bearing. [verify-upheld] |
| TS-05 | ✅ | pyproject addopts includes '--strict-markers' and '--strict-config'. Independently confirmed: invoking under the mgf-standard venv (no pytest-asyncio config support) produced a hard INTE | Upheld. Both flags set and demonstrably enforced (reproduced the strict-config failure). [verify-upheld] |
| TS-06 | ✅ | [tool.coverage.report] fail_under=80; [tool.coverage.run] source=['src/mgf/sqlalchemy'], branch=true. Measured run: TOTAL 95.03% (135 stmts, 3 miss, 26 branch, 5 BrPart). Per-module: __init_ | Upheld. Gate at 80, actual 95.03% with branch coverage; exclusions clean; coverage is behavioral (RLS bite, SQL-shape, injection corpus) not tautological. Exact missing-line claim reproduced. [verify-upheld] |
| TS-07 | N/A | Not in the challenge set; not adjudicated in this refute pass. | Out of scope for this adversarial pass. |
| TS-08 | N/A | Not in the challenge set; not adjudicated in this refute pass. | Out of scope for this adversarial pass. |
| TS-09 | N/A | Not in the challenge set; not adjudicated in this refute pass. | Out of scope for this adversarial pass. |
| TS-10 | ✅ | SH-01: test_tenant_session_security.py:32-65 parametrizes 26 adversarial inputs, asserts ValueError and session.execute.assert_not_called() BEFORE execute (:89-96), plus positive counter-tes | Upheld. Every security-relevant rule has a pin asserting the negative/leak case; the injection corpus matches the §10.1 negative-pattern shape. [verify-upheld] |
| TS-11 | N/A | No GUI surface — adapter library, no PySide6/Qt workers. Carve-out confirms PR-03/04/05 N/A. | GUI-worker rule does not apply to a headless async-SQLAlchemy adapter. |
| TS-12 | ✅ | pyproject [dev] lists pytest-asyncio>=0.23; asyncio_mode='strict' + asyncio_default_fixture_loop_scope='function' (per-test loop). Async surfaces covered: engine round-trip (test_engine.py:3 | Upheld. pytest-asyncio used, per-test loop scope, every async surface (tenant_session, engine.connect) has a test. [verify-upheld] |
| TS-13 | N/A | Not in the challenge set; not adjudicated in this refute pass. | Out of scope for this adversarial pass. |
| TS-14 | ✅ | tests/perf/test_engine_construction.py:50-89 (@pytest.mark.perf, class-level :50) measures create_engine via the src path over N=100 constructions with warmup, 200µs/construction budget stat | Upheld. Perf benchmarks measure the real create_engine/tenant_session paths, are perf-marked, regression-threshold-shaped, and excluded from the per-PR default. [verify-upheld] |
| TS-15 | ✅ | tests/integration/test_rls_nosuperuser.py is opt-in (pytestmark=pytest.mark.integration:56, deselected by default). Creates a uniquely-named schema+role (_SCHEMA=mgf_rls_test_<uuid4hex[:12]> | Upheld. The mutating real-backend smoke is marker-gated, hermetic (unique scratch schema/role), self-cleaning on success and failure, and documented — matching §12's five rules. (Minor: the skip/cleanup lives in the fixture, not at the body |
| TS-16 | ✅ | f-string context messages: test_tenant_session_security.py:90-96 (execute.assert_not_called with boundary comment); test_engine.py:65-67 (unmasked-value f-string); RLS bite emits 'LEAK: tena | Upheld. Assertions use f-string context where a bare assert would be ambiguous, satisfying the self-explanatory-failure MUST. [verify-upheld] |
| TS-17 | ✅ | find tests -name conftest.py returns NONE. Fixtures are file-local: audit_engine/soft_engine in test_mixins.py:122/259, rls_fixture in test_rls_nosuperuser.py:123. grep for 'from ...conftest | Upheld. Every fixture is file-local (lowest valid scope); no cross-package fixture import exists. [verify-upheld] |
| TS-18 | ✅ | pyproject markers declare 'slow: legacy marker for tests >1s wall-clock (TS-18). Deprecated. Removed in v2.0.' Default addopts excludes '-m not perf and not slow and not stress and not e2e a | Upheld. slow is defensively registered and default-excluded; the long-running test is the smoke supervisor self-check, marked smoke with an explicit 90s timeout override. [verify-upheld] |
| TS-19 | ✅ | pyproject [tool.pytest.ini_options].markers declares the full 13-layer taxonomy (smoke, e2e, integration, contract, property, regression, fuzz, concurrency, conformance, use_case, perf, stre | Upheld. Every marker the tests use is registered; the two-axis requirement is met; --strict-markers enforces it. [verify-upheld] |
| TS-20 | ✅ | tests/unit/ (default, mirrors src), tests/integration/ (test_rls_nosuperuser.py pytestmark=integration:56), tests/smoke/ (test_mtest_self_check.py pytestmark=smoke:35), plus tests/perf/. Eac | Upheld. unit/integration/smoke directories present with matching pytestmark; the missing e2e layer is appropriate for this shape. [verify-upheld] |
| TS-21 | ✅ | tests/smoke/ contains ONLY __init__.py and test_mtest_self_check.py — the latter is the supervisor self-check (subprocess invoking 'python -m mgf.test_supervisor --self-check', ~32s), NOT th | Refuted. A smoke directory exists but its sole test is the supervisor self-check, not the published-library smoke shape TS-21 mandates. No test in any layer iterates the full __all__ ([AuditTrailMixin, SoftDeleteMixin, create_engine, create — FIXED 2026-06-07 (0.5.6): tests/smoke/test_imports_smoke.py — canonical smoke (imports + every __all__ reachable + __version__) |
| TS-22 | ✅ | pyproject [dev] pins mgf-test-supervisor>=0.1.3,<0.2 (installed at .venv/.../mgf/test_supervisor). Submodules confirmed present: __main__, diagnostics, durations, quarantine, records, select | Upheld. The four-tier supervisor is an installed dev dep, tiers module importable, and tier assignment is reflected in the run records. [verify-upheld] |
| TS-23 | ✅ | pyproject wires pytest-timeout>=2.3,<3 ([dev]) with timeout=30, timeout_method='thread', faulthandler_timeout=60. mgf.test_supervisor.supervisor importable (runs pytest as subprocess). .gate | Upheld implicitly (not in the explicit-challenge subset but its supervisor mechanism is corroborated by TS-22/24/25/27 evidence). |
| TS-24 | ✅ | .gates/last-run/run.jsonl is one JSON object per line; verified keys: test_id, outcome, severity, duration_ms, tier, markers, code, summary, detail, why, remediation, captured_stdout, captur | Upheld. Structured per-test records with the mandated schema + mandatory schema_version, mirroring TestRecord, written by the conformant supervisor's records module. [verify-upheld] |
| TS-25 | ✅ | .gates/quarantine.json present (26463 bytes, mode 0600 / -rw-------). Managed by mgf.test_supervisor.quarantine (imports OK). .gates/ is gitignored (.gitignore:67 '.gates/'), keeping state C | Upheld. Auto-quarantine state file present, mode 0600, managed by the conformant supervisor's quarantine module; gitignored. [verify-upheld] |
| TS-26 | N/A | Pure-Python library; no compiled artifact (Zig/Go/Rust/C/Swift). pyproject build-backend is hatchling with no native deps; runtime deps are mgf-common + sqlalchemy[asyncio]. | TS-26 explicitly permits pure-Python libraries to declare it N/A (no binary freshness to check). |
| TS-27 | ✅ | .gates/last-run/failures/ holds one .txt per test with ordered sections (verified: === test_id ===, === outcome ===, === code ===, === summary ===, === duration_ms ===, === tier ===, === mar | Upheld. Single-file failure bundles with the mandated section structure are produced by the conformant supervisor; the stale bundles are MISSING_FROM_XML harness artifacts, not real failures. [verify-upheld] |
| TS-28 | ⏳ | The claim asserts the perf-attribution reader is 'mgf.test_supervisor.perf' — that module DOES NOT EXIST: `import mgf.test_supervisor.perf` raised ModuleNotFoundError, and pkgutil.iter_modul | Refuted. TS-28 is L2 and may be deferred by L1 projects, but this claim affirmatively states the reader is mgf.test_supervisor.perf and that the mechanism is adopted/surfaced — both false: the reader module does not exist, the on-disk schem |

### API_DESIGN

| Rule | Status | Evidence | Notes |
|---|---|---|---|
| AP-01 | ✅ | __init__.py:52-64 explicit sorted string __all__ (11 names); per-module __all__ at _engine.py:169, _session.py:240-243, _pagination.py:114, _mixins.py:109-116. tests/unit/test_engine.py asse | Verified by reading all 5 modules: every package and module boundary enumerates its public surface via an explicit, sorted, string-only __all__. The MUST of AP-01 (explicit __all__ at each boundary) is met. The absence of a full mirror-test |
| AP-02 | ✅ | create_engine (_engine.py:78-124), make_safe_url (:27-39), create_sessionmaker (_session.py:48-67), tenant_session (:98-210), paginate_cursor (_pagination.py:45-97), uuid7 (_mixins.py:124-15 | All 11 public names carry substantive docstrings stating intent + invariants + usage; most include explicit 'Use as::'/'Compose like::' examples. None match the 'returns the X' anti-pattern. AP-02 met. [verify-upheld] |
| AP-03 | ✅ | pyproject.toml:3 version="0.5.5" (MAJOR.MINOR.PATCH); :37-45 document 0.x pin discipline; PUBLIC_API.md states the 0.x window applies and prescribes tight consumer pins (>=0.X.0,<0.Y). | SemVer triplet form confirmed; operating in the documented 0.x window where MINOR may break, with consumer-side tight-pin guidance. AP-03 met. [verify-upheld] |
| AP-04 | N/A | No deprecations exist in the public surface through v0.5.5: no warnings.warn / DeprecationWarning / @deprecated in src/mgf/sqlalchemy/*.py (none found); the only 'deprecated' references are  | AP-04 governs the deprecation cycle; with zero deprecations shipped there is nothing to exercise the announce->survive->remove cycle. N/A for the current surface (same posture as mgf-common AS-IS §15). |
| AP-05 | ✅ | create_engine(database_url, *, echo, pool_pre_ping, pool_recycle, pool_size, max_overflow, **extra) (_engine.py:68-76); create_sessionmaker(engine, *, expire_on_commit=False, **extra) (_sess | Every additive option is keyword-only behind '*' with a default. The collision guards are a hardening beyond the rule. Signatures are AP-05-stable for the current surface. AP-05 met. [verify-upheld] |
| AP-06 | ✅ | Returns pinned narrowly: create_engine->AsyncEngine (_engine.py:77); make_safe_url->str (:26); create_sessionmaker->async_sessionmaker[AsyncSession] (_session.py:47); paginate_cursor->tuple[ | All public returns are concrete, narrowly-pinned types (e.g. list[T] not Iterable[T]), so the no-narrowing/no-subtle-widening contract is well-positioned and presently honoured. AP-06 met. [verify-upheld] |
| AP-07 | ✅ | Public functions raise documented, standard exceptions: tenant_session raises ValueError (non-UUID, _session.py:217) and RuntimeError (not-in-transaction, :231) — both documented in the docs | Every public failure mode raises a stdlib exception type that is documented in the raising function's docstring. The standard says exceptions MUST subclass the project's AppError hierarchy — here the library deliberately raises stdlib Value |
| AP-08 | ✅ | grep -L 'from __future__ import annotations' over src/mgf/sqlalchemy/*.py returned empty (all 5 modules have it: __init__.py:38, _engine.py:18, _session.py:21, _pagination.py:24, _mixins.py: | Confirmed directly via grep -L (empty result). Every public module uses future-annotations and isolates type-only imports under TYPE_CHECKING. AP-08 met. [verify-upheld] |
| AP-09 | ✅ | ls confirms src/mgf/sqlalchemy/py.typed exists (0-byte). pyproject.toml:107-108 [tool.hatch.build.targets.wheel] packages=["src/mgf"] walks the tree so the marker ships. classifiers include  | PEP 561 marker present and packaged. The marker MUST of AP-09 is met. Note (consistent with the claim): there is no .woodpecker CI py.typed/unzip post-build pin — grep over CI config found none — but that is the §14 mechanical-enforcement s |
| AP-10 | ✅ | PUBLIC_API.md exists at repo root, listing every public name with a Tier column and a one-line description (rows for create_engine/create_sessionmaker/tenant_session/paginate_cursor and the  | The AP-10 MUST — a PUBLIC_API.md listing every public name with stability tier and one-line description — is satisfied; the doc covers all 11 __all__ names. The 'CI check keeps it in sync with __all__' clause is unmet (no sync test present) |
| AP-11 | ✅ | PUBLIC_API.md declares a Tier column and tiers every public name 'experimental' (lines 35-40+); _mixins.py:3 docstring states 'Stability tier: experimental (AP-11)'. The three tiers experime | Stability tiers are declared per public name (all currently 'experimental', consistent with the 0.x convention). AP-11's MUST (a declared tier per name) is met. No automated tier-column pin test found, but the declaration itself satisfies t |
| AP-12 | ✅ | CHANGELOG.md:289-298 'Removed (BREAKING vs the pre-extraction mgf.common.db shape)' documents get_session/setup_db removal: what was removed, why (closed-box rule — no Starlette/FastAPI in t | The one breaking entry carries before/after location, why, and a transformation recipe. The literal §10.1 'exact symptom' line is thinner than the model template (this is a removal-vs-prior-package, so there is no in-place TypeError symptom |
| AP-13 | ✅ | grep -rn '__version__' src/ returned NOTHING — there is no __version__ attribute on the top-level mgf.sqlalchemy package (or any module). pyproject.toml:3 has version="0.5.5" but nothing mir | AP-13 is a MUST: a __version__ attribute MUST be present on the top-level package and mirror pyproject.toml::project.version, with a CI lint keeping them in sync. The package is a PEP 420 namespace sibling whose __init__.py (read in full) d — FIXED 2026-06-07 (0.5.6): mgf.sqlalchemy.__version__ added (mirrors pyproject) + CI tag-coherence asserts it |
| AP-14 | 🚫 | All implementation lives in single-underscore modules (_engine/_session/_pagination/_mixins) re-exported via __init__.py, and the package docstring states consumers MUST NOT reach into _engi | The closed-box layout (private _ modules, public re-exports) is correct, but AP-14's MUST is that CI MUST enforce via import-linter that tests/consumers don't import _ modules. With import-linter installed yet NO contract configured anywher — DECLINED 2026-06-07 (CFM-04 §3): the import-linter enforcement targets CONSUMER test fixtures; this adapter has NO in-repo consumer harness, and its own tests white-box `_` modules by design. Closed-box is in place (private `_` modules + complete `__all__` re-export + PUBLIC_API.md + the TS-21 public-surface smoke prove consumers never need `_` imports). A future in-repo consumer-smoke harness would close it mechanically. |
| AP-15 | N/A | No backward-compatibility shim modules exist in src/mgf/sqlalchemy/ — all 5 modules are first-class (no re-export-from-old-location shim, no module-import-time warnings.warn). The get_sessio | AP-15 governs shims that survive removal of the original code; this library ships none, so there is nothing required to emit DeprecationWarning + INFO audit log. N/A for the current surface. |

### SCOPE

| Rule | Status | Evidence | Notes |
|---|---|---|---|
| SP-01 | ✅ | No SCOPE.md exists (find -iname '*scope*' over repo, excluding .venv/.git, returns nothing). grep for 'in scope'/'IN-scope' across README.md, PUBLIC_API.md, DEPS.md, CONTRIBUTING.md, STARTHE | SP-01 binds: mgf-sqlalchemy is exactly the 'cornerstone-shaped shared infrastructure library with downstream consumers' the standard targets (a federation sibling consumed by PlasmaMapper + mgf-fastapi per DEPS.md:39-54). The MUST is an *ex — FIXED 2026-06-07: SCOPE.md §1 in-scope policy |
| SP-02 | ✅ | No OUT-of-scope list with reasoning exists. The closest content is scattered prose: README.md:25-31 'FastAPI helpers live elsewhere... This sibling stays framework-agnostic' and PUBLIC_API.m | SP-02 binds (same cornerstone shape). It requires an explicit OUT-of-scope list where every entry pairs reasoning with an alternative. The 'lives in mgf-fastapi' notes cover only the federation-internal split, not the ecosystem cuts an SQLA — FIXED 2026-06-07: SCOPE.md §2 out-of-scope + alternatives |
| SP-03 | ✅ | CONTRIBUTING.md (read in full, lines 1-60) defines the PR process — four-gate CI (ruff/mypy/pytest/coverage, lines 36-42), CHANGELOG entry (43-44), PUBLIC_API delta (45-46) — but has NO scop | SP-03 binds: it is a PROCESS MUST that every PR adding a new module or top-level function justify against an IN/Adjacent list. That justification cannot exist while SP-01/SP-02 (the §1/§3 targets it points at) are absent, and CONTRIBUTING.m — FIXED 2026-06-07: SCOPE.md §3 scope-creep gate |
| SP-04 | ✅ | No Adjacent-scope section exists anywhere; grep for 'adjacent' across all docs returns nothing. FEEDBACK.md is present (the demand-signal channel exists, referenced README.md:146-149) and DE | SP-04 binds: it governs how items move from Adjacent->IN. With no Adjacent list defined (SP-01/SP-03 gap), the promotion-gate rule has nothing to attach to and is undocumented. Smallest fix: add a §3 Adjacent section to the scope doc statin — FIXED 2026-06-07: SCOPE.md §4 adjacent-scope + demand-signal |
| SP-05 | ✅ | No OUT-of-scope list exists, so no per-cut ecosystem citation exists. The only ecosystem pointers present are the relocation notes (PUBLIC_API.md:67-76 -> mgf-fastapi; README.md:25-31). READ | SP-05 binds and is strictly downstream of SP-02: it requires every OUT cut to name the ecosystem tool that does that job. Since the OUT list itself is absent (SP-02 ⏳), the citation requirement is unmet by construction. Smallest fix: when a — FIXED 2026-06-07: SCOPE.md §5 ecosystem alternatives per OUT cut |
| SP-06 | ✅ | No scope document exists, hence no '## Versioning of this document' table and no statement that scope is revisited on every MAJOR release. grep for 'MAJOR release.*scope'/'revisit' across al | SP-06 binds as a maintenance-discipline MUST: the scope policy must be revisited at every MAJOR boundary, and that revisit discipline must be documented. It cannot be satisfied without a scope doc to revisit (SP-01 gap). Pre-1.0 status does — FIXED 2026-06-07: SCOPE.md §6 revisit-on-MAJOR |

### WORKFLOWS

| Rule | Status | Evidence | Notes |
|---|---|---|---|
| WF-01 | ✅ | .woodpecker.yml:13-16 — `when:` declares `event: push`, `event: pull_request`, `event: manual` with NO branch filter. Header comment lines 4-5: 'Runs on every push / PR.' | [verify-upheld] Tried to refute by looking for a branch restriction or a missing event — neither exists. Both required events (push, pull_request) are present and unrestricted by branch, so CI fires on every push to every long-lived branch  |
| WF-02 | ✅ | .woodpecker.yml has lint (line 21, `ruff check src tests`), typecheck (line 29, `mypy`), and per-version test gates (lines 41/48/55, `pytest`). The fourth gate — import-linter / `lint-import | WF-02 names FOUR green gates (lint / typecheck / test / import-linter). Three are CI-enforced; the import-linter gate is not present and no `.importlinter` contracts exist. The workflow self-documents the omission as deliberate (no contract — FIXED 2026-06-07: tag-driven Codeberg publish pipeline (.woodpecker build→tag-coherence→smoke→publish→verify-codeberg) + .importlinter closed-box contract & lint-imports in CI + scripts/verify_codeberg.py; mirrors mgf-common/mgf-fastapi |
| WF-03 | ✅ | .woodpecker.yml has NO publish step and NO `event: tag` trigger. Header comment lines 5-6: 'No publish flow yet — when a release is cut, copy the tag-coherence -> smoke -> publish -> verify- | WF-03 requires that a library publishing an mgf-* package MUST have a tag-driven publish workflow targeting the Codeberg registry. mgf-sqlalchemy publishes mgf-* wheels (it is at 0.5.5 and resolved as a sibling from the Codeberg index), but — FIXED 2026-06-07: tag-driven Codeberg publish pipeline (.woodpecker build→tag-coherence→smoke→publish→verify-codeberg) + .importlinter closed-box contract & lint-imports in CI + scripts/verify_codeberg.py; mirrors mgf-common/mgf-fastapi |
| WF-04 | N/A | No publish step exists in .woodpecker.yml (no `codeberg_package_token`, no `from_secret`, no upload). Confirmed no token / password / OIDC reference anywhere in the file. | WF-04 governs how publish credentials are stored. With no publish workflow present (see WF-03), there is no credential surface to audit — and importantly, the file commits the cardinal virtue: it contains NO tokens. The rule cannot be satis |
| WF-05 | ✅ | No tag-coherence check in .woodpecker.yml (no publish flow). Additionally, `__version__` does NOT exist anywhere under src/ (grep for `__version__` in src/ returns nothing), so the WF-05 che | WF-05 requires the publish workflow to verify tag↔pyproject↔__version__ coherence before upload. There is no publish workflow, so the check is absent. Worse, the package exposes no `__version__` attribute, so the AP-13 / WF-05 invariant has — FIXED 2026-06-07: tag-driven Codeberg publish pipeline (.woodpecker build→tag-coherence→smoke→publish→verify-codeberg) + .importlinter closed-box contract & lint-imports in CI + scripts/verify_codeberg.py; mirrors mgf-common/mgf-fastapi |
| WF-06 | ✅ | No build/publish step in .woodpecker.yml. A pre-built `dist/` directory exists in the working tree (drwxrwxr-x dist, last modified Jun 4) — exactly the stale-artifact reuse risk REL-02/WF-06 | WF-06 requires the uploaded wheel to be built fresh in the publishing CI run. No publish run exists, and the only wheels are local `dist/` artifacts on a developer machine — the precise drift hazard the rule forbids. Gap → ⏳. (Not in the ✅ — FIXED 2026-06-07: tag-driven Codeberg publish pipeline (.woodpecker build→tag-coherence→smoke→publish→verify-codeberg) + .importlinter closed-box contract & lint-imports in CI + scripts/verify_codeberg.py; mirrors mgf-common/mgf-fastapi |
| WF-07 | ✅ | No pre-publish smoke step in .woodpecker.yml. No ephemeral-venv wheel-install + import + `__version__` assertion anywhere (and no `__version__` to assert, per WF-05 evidence). | WF-07 requires a pre-publish smoke that installs the freshly-built wheel into a clean venv and imports the top-level package + `__version__`. Absent (no publish flow; no `__version__`). Gap → ⏳. (Not in the ✅ challenge set.) — FIXED 2026-06-07: tag-driven Codeberg publish pipeline (.woodpecker build→tag-coherence→smoke→publish→verify-codeberg) + .importlinter closed-box contract & lint-imports in CI + scripts/verify_codeberg.py; mirrors mgf-common/mgf-fastapi |
| WF-08 | ✅ | No post-publish verify step in .woodpecker.yml. No poll of the Codeberg REST API `…/api/v1/packages/magogi-admin/pypi/mgf-sqlalchemy/<version>`. | WF-08 requires post-publish verification against the Codeberg registry. Absent (no publish flow). Gap → ⏳. (Not in the ✅ challenge set.) — FIXED 2026-06-07: tag-driven Codeberg publish pipeline (.woodpecker build→tag-coherence→smoke→publish→verify-codeberg) + .importlinter closed-box contract & lint-imports in CI + scripts/verify_codeberg.py; mirrors mgf-common/mgf-fastapi |
| WF-09 | ✅ | .woodpecker.yml interpreter images are explicit minor pins: `python:3.12-slim` (lines 22/30/49/64), `python:3.11-slim` (42), `python:3.13-slim` (55); the only third-party plugin image is an  | [verify-upheld] Tried to refute by hunting for any floating or unversioned ref — found none. WORKFLOWS.md §7.1 explicitly accepts rolling-minor `python:3.12-slim` ('Most projects accept rolling-minor for the security-update benefits'), and  |
| WF-10 | ✅ | .woodpecker.yml:18-77 — all seven steps (lint, typecheck, test-3.11, test-3.12, test-3.13, vuln-scan, secret-scan) declared with NO `depends_on:` anywhere, so Woodpecker schedules them in pa | [verify-upheld] Tried to refute by searching for any `depends_on` edge that would needlessly serialise independent gates — there are zero. Every gate is independent and parallel by default, and the three per-version test steps fan out the v |
| WF-11 | ⏳ | uv.lock IS checked into the repo (237 KB, pyproject.toml:87-97 wires `[[tool.uv.index]]` codeberg-mgf + `[tool.uv.sources]`). BUT every CI step installs via `pip install --quiet -e ".[dev]"` | WF-11 requires a CI run reproducible from its inputs alone, and §7.1 names the lockfile as the mechanism: 'CI installs from lock.' Here a lockfile exists but CI bypasses it, installing from unpinned ranges (`mgf-common>=0.41,<0.47`, `sqlalc |
| WF-12 | ✅ | .woodpecker.yml — no `\|\| true` and no error-swallowing anywhere. Each gate is its own named step in a fresh container (header lines 8-9: 'does its own pip install so failures are per-step  | [verify-upheld] Tried to refute by searching for any `\|\| true`, `set +e`, trailing `; true`, or a no-op step that would green-tick on skip — found none. Every step is independently named so a red tick maps to one command, and `--tb=short` |
| WF-13 | ✅ | .woodpecker.yml is a generated artifact — header "GENERATED — do not hand-edit", rendered from mgf-standard/templates/woodpecker/ by mgf-fed; not hand-maintained. |

### RELEASING

| Rule | Status | Evidence | Notes |
|---|---|---|---|
| REL-01 | ✅ | v0.5.5 latest tag is LIGHTWEIGHT (git cat-file -t = commit); prior v0.2.0..v0.5.4 annotated. Points at the right commit 8b6e197. | REL-01 requires annotated v<ver> tags. v0.5.5 is lightweight (GC-eligible, no metadata). Fix: re-annotate + force-push. — FIXED 2026-06-07: the lightweight v0.5.5 tag re-annotated on its original commit 8b6e197 + force-pushed (authorized); verified type=tag. v0.5.6/v0.5.7 annotated |
| REL-02 | ✅ | git tag yields 10 unique tags (v0.2.0,v0.4.0..v0.4.2,v0.5.0..v0.5.5), count==unique==10, no two tags resolve to the same commit (uniq -d on rev-list returns empty). dist/.gitignore='*' and ` | REL-02 MUST: a version string must not be reused across different wheel contents. Verified — gitignored build cache, monotonic bumps, one commit per tag, the on-disk 0.5.4 wheel was built at the v0.5.4 tag commit (not a later rebuild). The  |
| REL-03 | ✅ | PUBLIC_API.md lines 3-6 carry the banner verbatim: '⚠️ This file documents `master` HEAD. Names listed here may be unreleased. To learn what your installed wheel actually ships, run `pip sho | REL-03's binding MUST is the master-HEAD-not-published banner on PUBLIC_API.md (closes PAPER-12). It is present and correctly worded. The PUBLIC_API.json __version__ verification is a consumer-side check; this project ships no PUBLIC_API.js |
| REL-04 | ✅ | .woodpecker.yml header comment states 'No publish flow yet — when a release is cut, copy the tag-coherence -> smoke -> publish -> verify-pypi chain from mgf-common.' The workflow's only step | REL-04 MUST: publish tokens not passed via chat/shell-history/env-vars in unmanaged sessions; CI uses a tag-scoped platform secret. No token literal or secret reference appears anywhere in-tree, and CI has no publish step that could leak on |
| REL-05 | ✅ | No content-swap evidence: each consecutive tag pair has distinct, non-empty diffs (v0.5.1..v0.5.2: 5 files/103+/64-; v0.5.2..v0.5.3: 10 files; v0.5.3..v0.5.4: 18 files; v0.5.4..v0.5.5: 4 fil | REL-05 MUST: a published version is immutable; fixes ship as a new release, never a content swap. Observed practice — every change is a fresh monotonic bump, each tag a distinct content set — satisfies immutability-by-policy. No silent repl |
| REL-06 | ✅ | .woodpecker.yml header: 'No publish flow yet — copy the chain from mgf-common'; only lint/typecheck/test/vuln/secret steps; no release script. | No codified ordered release flow (bump→build→test→tag→publish→verify); ad-hoc by hand. Fix: port the mgf-common tag-gated publish chain. — FIXED 2026-06-07: tag-driven Codeberg publish pipeline (.woodpecker build→tag-coherence→smoke→publish→verify-codeberg) + .importlinter closed-box contract & lint-imports in CI + scripts/verify_codeberg.py; mirrors mgf-common/mgf-fastapi |
| REL-07 | ✅ | FEEDBACK.md has exactly one entry (grep -c id="paper => 1): PAPER-01. Its Status row (line 45) is '\| Status \| ✅ SHIPPED \|', 'Shipped in \| v0.5.0 (commit c593891)' (line 52), and a 'Retro | REL-07 MUST: a release commit closes every FEEDBACK entry it ships, flipping to ✅ SHIPPED with a one-paragraph retrospective. The sole entry PAPER-01 is flipped to ✅ SHIPPED with a retrospective body and the shipping version (v0.5.0). Satis |
| REL-08 | ✅ | No wheel smoke-install anywhere; test matrix uses pip install -e . (editable, not the built wheel); dist/ holds only stale 0.5.4 artifacts. | REL-08 wants a fresh-wheel smoke install + import. Fix: add a smoke step gating publish. — FIXED 2026-06-07: tag-driven Codeberg publish pipeline (.woodpecker build→tag-coherence→smoke→publish→verify-codeberg) + .importlinter closed-box contract & lint-imports in CI + scripts/verify_codeberg.py; mirrors mgf-common/mgf-fastapi |
| REL-09 | N/A | v0.5.5 (commit 8b6e197) touches only CHANGELOG+pyproject — a pure mgf-common pin-ceiling cohort walk; no FEEDBACK status flipped (PAPER-01 shipped in v0.5.0). | REL-09's premise (a FEEDBACK status flip in the release) doesn't bind — v0.5.5 closes zero FEEDBACK entries. |

### PACKAGE_DISTRIBUTION

| Rule | Status | Evidence | Notes |
|---|---|---|---|
| PKG-01 | ✅ | pyproject.toml dependencies pin mgf-common>=0.41,<0.47 with [tool.uv.sources] mgf-common = { index = "codeberg-mgf" } steering resolution to the Codeberg simple index (url .../api/packages/m | Every mgf-* dependency is sourced from the Codeberg registry via [tool.uv.sources]; the simple-index URL is the canonical one. Third-party deps (sqlalchemy, asyncpg, etc.) correctly resolve from public PyPI, which §1 permits. |
| PKG-02 | ✅ | pyproject.toml [[tool.uv.index]] url = "https://codeberg.org/api/packages/magogi-admin/pypi/simple/" — byte-for-byte the §3 simple-index endpoint. Repo-wide grep for codeberg.org/api/package | The only Codeberg package endpoint in committed config matches §3 verbatim with no hand-typed variant. Because the repo has no committed publish or verify command at all, there is no divergent-endpoint counterexample to find. [verify-upheld |
| PKG-03 | N/A | .woodpecker.yml defines lint/typecheck/test-3.11..3.13/vuln-scan/secret-scan only; there is no publish step and thus no token reference (no codeberg_package_token, no plaintext token). No ~/ | PKG-03 governs the auth token used to publish/install mgf-* on Codeberg. This repo commits no publish flow and no token, so there is no token-handling surface in-repo to conform or violate. Token discipline lives at the maintainer/CI-secret |
| PKG-04 | N/A | .woodpecker.yml has no build/twine-check/upload/verify/tag chain (explicit comment: 'No publish flow yet — when a release is cut, copy the ... chain from mgf-common'). dist/ holds locally-bu | The ordered publish ritual is a release-time procedure not committed to this repo (deferred to a copy from mgf-common at release time). With no publish flow in committed config there is nothing in-repo to evaluate for ordering. |
| PKG-05 | N/A | No verify step exists in .woodpecker.yml; the header comment even names the future step 'verify-pypi' (a stale label) to be copied later. No committed command queries the Codeberg REST API o | Post-publish verification is a release-time CI step this repo has not yet adopted. There is no committed verify command targeting pypi.org (which would violate) nor Codeberg (which would conform) — nothing in-repo to judge. |
| PKG-06 | ✅ | pyproject.toml: [[tool.uv.index]] name="codeberg-mgf", url=".../pypi/simple/", explicit = true; then [tool.uv.sources] mgf-common = { index="codeberg-mgf" } and mgf-test-supervisor = { index | Exactly the §6 canonical shape: named explicit index closing the dependency-confusion hole + per-package source mapping for every directly-pinned mgf-* dependency. explicit=true means only mapped names resolve from Codeberg. This is the str |
| PKG-07 | N/A | No delete/re-upload command or recovery procedure is committed; CHANGELOG records normal version bumps with no silent-replacement notes. The immutability/recovery capability is a registry op | PKG-07 governs an operational delete+re-upload escape hatch exercised at release time against the live registry. There is no committed surface for it in this library repo, so it is not applicable to the in-repo audit. |
| PKG-08 | N/A | No retention/quota tooling, scheduled prune job, or quota-tracking script exists in the repo (scripts/ holds only __init__.py). Retention is an account-level (magogi-admin) operation across  | PKG-08 retention is an org/account-wide policy run against the registry quota, not a per-library-repo artifact. mgf-sqlalchemy has no retention surface to conform or violate. |
| PKG-09 | N/A | .woodpecker.yml when-clause is event: push / pull_request / manual with NO tag-driven publish step. No build-in-CI publish, no codeberg_package_token secret, no event: tag gating. The header | PKG-09 governs tag-driven CI publishing. This repo has not yet wired any publish step into CI, so there is no tag-driven publish flow to evaluate. No non-conformance exists because no publish runs at all; the requirement simply hasn't been  |
| PKG-10 | ✅ | pyproject.toml name = "mgf-sqlalchemy" (hyphenated dist); [tool.hatch.build.targets.wheel] packages=["src/mgf"] PEP 420 namespace → dotted import mgf.sqlalchemy; dist/ normalized to mgf_sqla | Naming defers correctly to NM-01..04: hyphenated dist name, dotted namespace import, PEP 503-normalized artifacts, and the canonical 'where to find it' URL in pyproject.toml is the Codeberg package page. The pypi.org README badges are a dis |
| PKG-11 | N/A | Repo contains no agent/federation version-check tooling (no gen_mgf_libraries-style script; scripts/ is empty bar __init__.py). Version-resolution-against-Codeberg is a federation-CLI / agen | PKG-11 binds agents performing published-version checks; mgf-sqlalchemy ships no such logic. Not applicable to this library's committed surface. |
| PKG-12 | ✅ | Residual pypi.org distribution/display surface for mgf-* packages persists: README.md lines 3-4 PyPI version/python badges link https://pypi.org/project/mgf-sqlalchemy/; line 8 'PyPI metadat | PKG-12 permits pypi.org references only for third-party packages or clearly-historical notes. Multiple residual mgf-* references are neither: the README PyPI version/python badges and 'PyPI metadata' link present pypi.org as the live 'where — FIXED 2026-06-07 (0.5.6): README badges/links retargeted off pypi.org → Codeberg (0 pypi.org refs remain) |

### DOCUMENTATION

| Rule | Status | Evidence | Notes |
|---|---|---|---|
| DOC-01 | ✅ | Repo-root ls confirms all ten uniform-baseline docs: README.md, LICENSE, CHANGELOG.md, CONTRIBUTING.md, SECURITY.md, FEEDBACK.md, AGENTS.md, STARTHERE.md, DEPS.md, FEDERATION.md — plus LESSO | The full v2.11/v2.12 + DOC-19 root-doc baseline + docs/ dir all exist for this sibling. PUBLIC_API.json absence is a DOC-08 concern, not the DOC-01 baseline list (which is .md only). No counterexample found. [verify-upheld] |
| DOC-02 | ✅ | docs/ contains standards/ (pointer-only README), claude/, cutover/, inprogress/, recipes/, plus an extra testing/ bucket. docs/standards/README.md:3 carries the literal 'NOT a duplicate' fra | Non-root docs are in the canonical buckets applicable to a sibling; standards/ is the permitted pointer-only shape. The missing testing/ README is a DOC-03 concern (explicitly an additional bucket without a charter), not a DOC-02 bucket-dis |
| DOC-03 | ✅ | docs/testing/ has DIAGNOSING_HANGS.md but NO README.md charter; the 5 canonical buckets do have one. | DOC-03 wants every bucket (incl. additional) to ship a charter README. Fix: add docs/testing/README.md. — FIXED 2026-06-07: docs/testing/README.md charter added |
| DOC-04 | ✅ | CHANGELOG.md:5 declares Keep a Changelog; line 20 has [Unreleased]; per-release Added/Changed entries match the public surface (paginate_cursor at [0.5.0] lines 77-93; the six _mixins names  | Public-API changes carry CHANGELOG entries that match the surface; the breaking release links its cutover guide. Same-commit landing is not git-verifiable from this snapshot, but every entry exists and corresponds to a real surface change.  |
| DOC-05 | ✅ | docs/cutover/v0.1.0.md exists for the only breaking release (the v0.30 extraction). At-a-glance table (lines 26-34) names every removed/relocated symbol with replacement (get_session/setup_d | The single breaking release ships a cutover guide with all mandatory DOC-05 sections (removed/renamed table, mechanical path, manual blocks). No FEEDBACK back-link, but DOC-05(d)/§5.1 makes the FEEDBACK row applicable only when a paper exis |
| DOC-06 | ✅ | docs/inprogress/RELIABILITY_AND_ACCURACY.md follows the six-section shape: §1 You are here (line 32) with a counts table (lines 48-53), §2 Priority table (line 60) with per-item Effort+Statu | The living trackers follow the canonical priority-tracker shape (priority table, work units with verified file:line + falsifiable concrete output). All items closed (counts line 48-53). No counterexample. MET. [verify-upheld] |
| DOC-07 | ✅ | docs/claude/CLAUDE.md (429 lines, non-empty) in dense-lookup format: File map table (line 319), Cross-cutting patterns (line 333), Build and release (line 379), Common pitfalls (line 396), R | The §4 dense-lookup CLAUDE.md ships in the mandated shape with facts/citations/pitfalls and no marketing prose. The duplicate docs/CLAUDE.md is a minor housekeeping smell (DOC-11/DOC-02 hygiene), not a DOC-07 failure — the mandated file exi |
| DOC-08 | ✅ | No PUBLIC_API.json, no generator (scripts/ only __init__.py), no CI pin. PUBLIC_API.md exists but no machine companion. | DOC-08 wants PUBLIC_API.json generated from __all__ + CI-pinned. Fix: generator + json + pin test (mgf-fastapi/mts shape). — FIXED 2026-06-07 (0.5.6): PUBLIC_API.json + tools/generate_public_api_json.py + CI pin test |
| DOC-09 | ✅ | No See: back-refs in src; no name-existence lint test; only a one-symbol __all__ membership assert in test_engine.py:106. | DOC-09 wants a doc↔code drift mechanism (CI name-existence lint OR code back-refs). Fix: add a PUBLIC_API.md↔__all__ pin test. — FIXED 2026-06-07 (0.5.6): PUBLIC_API.md now lists every public name + a md↔__all__ name-existence pin test (test_public_api_doc_pin) |
| DOC-10 | ✅ | FEEDBACK.md is the consumer-facing flow: PAPER-01 (lines 41-52) carries Status/Severity/Submitter/Submitted/Decision metadata and the SHIPPED lifecycle with a 'Shipped in v0.5.0 (commit c593 | Consumer signal (FEEDBACK.md) and internal posture (docs/inprogress/) are distinct, non-cross-contaminated surfaces. No bleed of consumer papers into trackers or vice versa. MET. [verify-upheld] |
| DOC-11 | ✅ | docs/inprogress/README.md lines 1-8 state the 'workspace, not a graveyard' rule and the archive-within-one-cycle cadence. The three trackers are marked 'v0.1 — active' (README index lines 34 | DOC-11 archival is a SHOULD/maintenance signal, not a hard defect (§14 'No mechanical check'). The bucket README encodes the discipline and the fully-closed trackers have not sat a full release cycle warranting forced archival. The duplicat |
| DOC-12 | ✅ | Intra-repo cross-refs are relative (README.md:123-126 → docs/recipes/sqlalchemy.md, PUBLIC_API.md, CHANGELOG.md; docs/inprogress/README.md:28 → ../standards/README.md). Cross-repo refs use a | Docs are AI-navigable: relative intra-repo links, absolute only for cross-repo, hierarchical numbered headings, repo-rooted paths, no marketing prose. No counterexample found. MET. [verify-upheld] |
| DOC-13 | ✅ | FEEDBACK.md header (lines 8-13) states mgf-sqlalchemy-specific issues file HERE and federation-wide ones go to mgf-common/FEEDBACK.md. PAPER-01 (line 49) records 'Federation paper: PAPER-94  | FEEDBACK.md is correctly repo-scoped with the MOVED-paper cross-reference discipline applied (the federation source number preserved as a metadata row). MET. [verify-upheld] |
| DOC-14 | N/A | README:6 'Federation sibling of mgf-common'; ADP-04 explicitly carves siblings out of MGF_ADOPTION.md; repo correctly ships none. | DOC-14 binds consumer apps only; as a sibling, adoption lives in mgf-common's roadmap + CHANGELOG. Premise doesn't bind. |
| DOC-15 | ✅ | docs/inprogress/MGF_STANDARDS_CONFORMANCE.md present (596 lines), README:134-linked, L2 declared, per-rule rows for every MUST incl. DOC-19 ✅ + DOC-14 N/A; LESSON_LEARNED.md present. | DOC-15's MUST is presence + per-rule completeness of the ledger (CFM-03). Met — ⏳ is a valid CFM-03 marker; rule doesn't require all rows resolved. [verify-upheld] |
| DOC-16 | ✅ | DEPS.md at repo root: §1 'What mgf-sqlalchemy depends on' (mgf-common, sqlalchemy[asyncio], aiosqlite — lines 16-20) and §2 'Who depends on mgf-sqlalchemy' (PlasmaMapper + mgf-fastapi with i | The bidirectional manifest exists with both required sides + the import-survey gate. The pin-window drift vs pyproject and the PlasmaMapper→TelePlasma stale name are real quality/staleness defects, but DOC-16's structural MUST (both directi |
| DOC-17 | ✅ | FEDERATION.md (lines 1-18) is a pointer stub: states the contract is 'not maintained here — there is one canonical copy', links the canonical mgf-standard/FEDERATION.md, and at line 11 s | The sibling ships FEDERATION.md as the required pointer stub treating mgf-standard's copy as canonical, exactly per DOC-17. (Minor: the link prose says 'mgf-common/FEDERATION.md' while the URL targets mgf-standard — label drift, not |
| DOC-18 | ✅ | pyproject pins mgf-common>=0.41,<0.47 but DEPS.md §1 still lists >=0.40,<0.42 (stale). The pin↔DEPS.md coupling is out of sync. | DOC-18 wants coupled surfaces in sync. Fix: update DEPS.md §1 to >=0.41,<0.47 + re-stamp; ideally a pin test. — FIXED 2026-06-07: DEPS.md §1 mgf-common pin synced >=0.40,<0.42 → >=0.41,<0.47 + re-stamped |
| DOC-19 | ✅ | LESSON_LEARNED.md exists at repo root (956 bytes). Header lines 3-6 declare append-only/newest-first and cite DOC-19 + the lesson-learned-md-template. A dated seed entry '2026-06-07 — File s | DOC-19 (MUST since v2.21) requires the file to EXIST; a seeded template-shaped file with no real lessons yet is explicitly conformant (presence is the bar, per the rule text). The file is present and correctly shaped. MET. [verify-upheld] |

### OPERABILITY

| Rule | Status | Evidence | Notes |
|---|---|---|---|
| OP-01 | N/A | pyproject.toml has no [project.scripts]/console_scripts; there is no CLI and no service. src/mgf/sqlalchemy/ ships 5 library modules + __init__.py only. No --version surface, no /version end | OP-01 requires 'the app' to report a rich version on demand via a CLI --version or service /version. mgf-sqlalchemy is a thin importable library with no executable entrypoint and no running process, so there is no 'app' to query. Version id |
| OP-02 | N/A | No [project.scripts] in pyproject.toml; no doctor entrypoint in src/mgf/sqlalchemy/. The federation 'doctor' reference is mgf-common's `mgf-common doctor` (OPERABILITY.md §3), consumed by im | OP-02 mandates a `doctor` self-diagnostic COMMAND that probes the app's own state (config validity, stores well-formed). A pure adapter library has no persistent state of its own, no config store, no CLI to host the command. The consumer se |
| OP-03 | ✅ | pyproject.toml [project.urls]: Homepage/Issues/Changelog all point at https://codeberg.org/magogi-admin/mgf-sqlalchemy (real repo). grep of README.md/STARTHERE.md/pyproject.toml for 'github. | OP-03's MUST is that pyproject and printed URLs point at the real repo/docs/issue tracker — they do, with no placeholder. The 'CI MUST verify' clause is the one genuine gap: .woodpecker.yml has no curl -fsSI / no-placeholder grep step (no u |
| OP-04 | ✅ | grep -niE 'phase\|[0-9]+ tests\|src.file\|--version' over README.md/STARTHERE.md returned no test-count, no source-file-count, no phase marker. README.md:6-11 routes the mgf-common pin windo | OP-04's MUST is that headline facts in README/STARTHERE match reality; the 'CI SHOULD verify' half is explicitly a SHOULD. The README's design eliminates stale-fact risk by carrying no mechanical counts/pins/phase markers in prose and defer |
| OP-05 | N/A | No CLI (no [project.scripts]); no running service; no config store. create_engine(url, ...) takes config as call arguments from the consumer rather than owning a settings object. mgf-common' | OP-05 requires a RUNNING app to expose its active configuration via `<app> explain` or an admin /config endpoint. mgf-sqlalchemy holds no app-level configuration of its own — the consumer passes the DB URL/engine kwargs and owns the MgfSett |
| OP-06 | N/A | No CLI `logs` command, no GUI, no service log aggregator — none possible in an importable library. The library emits through mgf.common.observability into the CONSUMER's logging sink; it own | OP-06 mandates recent logs be reachable without source-tree path knowledge via `<app> logs` / GUI menu / aggregator URL. A library has no log sink of its own and no command host; log access is the consuming service's responsibility (its `<a |
| OP-07 | N/A | No [project.scripts] / bundle entrypoint; no crash-report dir, no config snapshot, no doctor output to bundle. OPERABILITY.md §3 marks the bundle command itself 'consumer-side' even in mgf-c | OP-07 requires a `bundle` diagnostic-tarball command aggregating redacted config + logs + crash reports + doctor output + system info — all artefacts a library does not own. The single bundle CLI is consumer-shaped (per the standard's own A |
| OP-08 | N/A | src/mgf/sqlalchemy/ writes no crash reports, no rotating logs, no caches. It manages a SQLAlchemy connection pool whose lifecycle the consumer controls (engine.dispose()); it creates no stat | OP-08 requires state directories (crash reports, log rotations, caches) to have bounded growth. mgf-sqlalchemy creates no such on-disk state — it is a stateless connection-factory/session adapter. There is no unbounded-growth surface to cap |
| OP-09 | N/A | Applies-to column = 'service'. mgf-sqlalchemy is a library, not a deployed service; it runs no validate_production() and opens no listener. pyproject.toml 'Development Status :: 3 - Alpha',  | OP-09 is an explicit service-only rule (production safety guards refusing dev-shaped values during config validation before listening). A leaf adapter library has no production environment of its own, no listener, no validate_production().  |
| OP-10 | N/A | Applies-to column = 'service'. No Dockerfile / compose / k8s manifest in the repo; the wheel is the only artefact and is published to PyPI/Codeberg under a semver tag (version 0.5.5), not de | OP-10 is service-only — it governs deployable container/image artefacts carrying stable version tags for rollback. A pip-installable library ships a semver-tagged wheel, not a `:latest` image, and has no deploy-manifest surface. N/A per app |
| OP-11 | N/A | Applies-to column = 'service'. No Prometheus rules, no alertmanager, no docs/runbooks/ alerting surface; .woodpecker.yml is CI-only. The library has no production deployment to alert on. | OP-11 is service-only — alert paging paths + per-alert runbook_url links. A leaf library is never the thing being paged on; the consuming service owns alerting. N/A per applies-to scope. |
| OP-12 | N/A | Applies-to column = 'service'. No backup script, no docs/drills/, no S3/R2/GCS target — mgf-sqlalchemy persists nothing of its own; it hands the consumer an engine/session against the consum | OP-12 is service-only — backup+restore drills against the real production storage target. A connection-factory library owns no data store and no backup story; the consumer's service runs DR drills against its own database. N/A per applies-t |

### DEPLOYMENT

| Rule | Status | Evidence | Notes |
|---|---|---|---|
| DEP-01 | N/A | DEPLOYMENT.md §Scope lines 7-9 binds rules to 'stateful web-service consumer applications'; Out-of-scope lines 20-21 explicitly exclude 'Federation libraries (no runtime)'. Rules-box 'Applie | DEP-01 requires every cloud resource (VM, LB, bucket, DNS, cert) be declared in IaC. mgf-sqlalchemy is an importable async-SQLAlchemy adapter library with NO cloud infrastructure — no VMs, no provisioned resources. The rule's premise (a dep |
| DEP-02 | N/A | Rules-box 'Applies to'=service. No VM/container deployment artefacts: no deploy/ansible, no Dockerfile (find returned empty). §8.4 notes DEP-02 is N/A even for managed-platform consumers; a  | DEP-02 (VM/container state as config-as-code) presupposes production VMs the project owns. A pip-installable library has no VM state to express as Ansible/cloud-init. Premise absent. |
| DEP-03 | N/A | Rules-box 'Applies to'=service. The rule governs deploy-time artefacts ('No pip install --upgrade at runtime in production'; image digests; lock at deploy). uv.lock exists but is the dev/bui | DEP-03's subject is the immutable artefact a service DEPLOYS to production. A library is consumed by downstream services that own their own lock/deploy immutability; the library itself is not deployed to a running production environment. Pe |
| DEP-04 | N/A | Rules-box 'Applies to'=service. No production secrets are owned here: no deploy/ansible/inventory/group_vars, no .env with prod values, secret-scan step (gitleaks v8.30.1) runs in CI. The li | DEP-04 (production secrets encrypted at rest in vault/KMS) presupposes a deployed service holding DB creds, signing keys, TLS keys. A library defines no production secret store; the consuming service owns secrets. Premise does not bind. |
| DEP-05 | N/A | Rules-box 'Applies to'=service. No deploy/scripts/deploy.sh exists (no deploy/ dir). scripts/ contains dev/CI helpers, not environment-explicit production deploy/backup/restore/rollback comm | DEP-05 (deploy/backup/restore/rollback scripts must take a prod\|staging\|dev arg) presupposes deployment scripts targeting production environments. A library ships no such scripts; there is no environment to deploy to. |
| DEP-06 | N/A | Rules-box 'Applies to'=service; rule cites OP-10. No release is deployed to a production target: no blue/green, symlink, tag-swap, or snapshot-restore path; no deploy/docs/runbook.md (no dep | DEP-06 (reversible deploy with drill-measured bounded rollback runbook) presupposes a deployed running service that can be rolled back. A library has no production rollout to reverse; the consuming service owns deploy rollback. |
| DEP-07 | N/A | Rules-box 'Applies to'=service; §3 mandates a top-level deploy/ directory. ls confirms no deploy/ directory exists. README.md:6 = 'Federation sibling' shape; DEPLOYMENT.md:20-21 excludes fed | DEP-07 (standard deploy/ directory shape with terraform/+ansible/+scripts/+monitoring/+docs) is required of 'every web-service consumer'. A library is not a web-service consumer in the deploy sense and owns no deployment artefacts; mandatin |
| DEP-08 | N/A | Rules-box 'Applies to'=service; requires committed deploy/docs/slo.md + burn-rate alerts + paging channel. No deploy/docs/slo.md exists (no deploy/ dir). The library USES mgf.common.observab | DEP-08 (production observable end-to-end with SLO file + alerts routing to a pager) presupposes a running production service the operator monitors. A library has no production deployment to observe; the consuming service owns the SLO and al |
| DEP-09 | N/A | Rules-box 'Applies to'=service. No DNS records or TLS certificates are owned by this project: no terraform DNS resources, no deploy/docs/dns.md (no deploy/ dir), no cert-renewal config. | DEP-09 (DNS records in IaC/committed list + auto-renewed TLS + expiry monitoring) presupposes a service with a public hostname and certificate. A library serves no traffic and owns no DNS/TLS; premise absent. |
| DEP-10 | N/A | Rules-box 'Applies to'=service; requires deploy/docs/first-production-cut.md documenting green-field provisioning. No such file exists (no deploy/ dir). There is no green-field cloud provisi | DEP-10 (first-production-cut runbook for end-to-end provisioning) presupposes infrastructure to provision (IaC applies, config playbooks, DNS cutover). A library provisions nothing; it is installed via pip by a consumer. Premise does not bi |
| DEP-11 | N/A | Rules-box 'Applies to'=service; requires deployability to ≥2 environments (prod + staging/dev) from shared IaC+config parameterised by an env file. No deploy/terraform/environments tree exis | DEP-11 (multi-environment deployability from the same code) presupposes deployable environments. A library has no environments to deploy to; it is imported into consumers' environments. Premise absent. |

### PRESENTATION_LAYER

| Rule | Status | Evidence | Notes |
|---|---|---|---|
| PR-01 | ✅ | src/mgf/sqlalchemy/ (5 modules) — grep for PySide6\|PyQt6\|qasync\|textual\|rich\|prompt_toolkit\|click\|typer\|fire\|flask\|fastapi\|django\|starlette\|jinja2\|mako returns ZERO real import | Substance (no UI-framework imports) is clean, but PR-01's second MUST clause (mechanical import-linter enforcement) is unmet: import-linter is installed but unwired — no forbidden-modules contract, no lint-imports CI step. Smallest fix: add — FIXED 2026-06-07: clause(b) mechanical enforcement now met by the .importlinter UI-forbid + lint-imports CI gate (this session's CI batch); clause(a) no-UI-import already held |
| PR-03 | N/A | PR-03's premise: 'An app repo with multiple UIs MUST separate UI-framework code...'. mgf-sqlalchemy is the domain SDK (src/mgf/sqlalchemy/ — engine/session/mixins/pagination/RLS adapter, pac | The rule binds an app repo with 2+ UIs. This is a pure-SDK library with no app side and no UI, so the premise does not bind. PR-07 itself authorizes marking PR-02..PR-05 as N/A for a pure-SDK sibling with zero UI consumers. Activates only i |
| PR-04 | N/A | PR-04's premise: 'The layer hierarchy MUST be enforced mechanically...' — it presupposes the PR-03 core/view/ui layer hierarchy, with contracts (a) core/view forbid UI frameworks and (b) ui/ | There is no app-side layer hierarchy to enforce, so the rule's premise is absent. (Note: SDK-level UI-framework enforcement is PR-01's job, separately verdicted ⏳; PR-04 is specifically the app-repo cross-layer/cross-UI contract, which has  |
| PR-05 | N/A | PR-05's premise: 'Each ui/<framework>/ adapter MUST consume view/ only — never another ui/<other>/'. It is meaningful only with 2+ sibling UIs (per §6: 'sibling-UI isolation is only meaningf | With zero UIs there are no sibling adapters that could cross-import, so the rule cannot bind. N/A per PR-07's explicit pure-SDK-with-zero-UI-consumers carve-out; activates at the first/second UI. |
| PR-07 | ✅ | PR-07 MUST: 'Conformance trackers MUST classify PR-* rules per the audit-outcomes taxonomy (✅ / ❌ / ⚪ / 🚫 / ⏳ / N/A)...'. docs/inprogress/MGF_STANDARDS_CONFORMANCE.md DOES contain a PR secti | PR-07 requires a genuine per-rule taxonomy classification with rationale, not a 'pending audit' placeholder. The tracker rows are scaffold echoing 'pending', so the classification mandate is not actually satisfied. Smallest fix: replace the — FIXED 2026-06-07: PR-* now classified per-rule with evidence in §Z (this depth-audit synthesis replaced the scaffold placeholders) |

### AGENTS

| Rule | Status | Evidence | Notes |
|---|---|---|---|
| AG-01 | ✅ | /home/bassam/PycharmProjects/mgf-sqlalchemy/AGENTS.md:1-37; `diff AGENTS.md /home/bassam/PycharmProjects/mgf-common/AGENTS.md` returns IDENTICAL. File is a thin pointer ('Run mgf-common agen | Refute attempt failed: AGENTS.md exists at root, is byte-identical to the federation template, briefing-free, and routes project-specific notes to CLAUDE.md exactly as AG-01 requires. [verify-upheld] |
| AG-02 | ✅ | AGENTS.md:9 points at the single source ('Run mgf-common agents'); docs/claude/CLAUDE.md:1 opens with a 'BEGIN mgf-common auto-generated — managed by mgf-common catch-up' block and line 10 s | Refute attempt failed: the canonical briefing is delegated to the mgf-common agents CLI (one federation-wide source); project lookups live in the catch-up-managed CLAUDE.md auto-block, not duplicated. [verify-upheld] |
| AG-03 | ✅ | git log shows agent commits 18e59de/9b06981/d814eaf each ending with BOTH 'Signed-off-by: Bassam Alsanie <bassam@magogi.org>' + 'Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthrop | Refute attempt failed: recent agent commits carry both trailers with the canonical signer + model+context Co-Authored-By, and .gitmessage enforces it going forward. The single older trailer-less bot commit predates the active convention and |
| AG-04 | ✅ | FEEDBACK.md exists at repo root; commit bodies (e.g. e07c2d6, fb615b4) reference PACKAGE_DISTRIBUTION/PKG papers and federation-wide consistency work routed through the paper pipeline. No si | The FEEDBACK channel exists and is used; no evidence of buried reusable-friction workarounds. Reviewer-enforced rule, observably honored. |
| AG-05 | N/A | Runtime/session-behavior rule about an agent verifying memory claims before acting; not a checkable repo artifact. | Self-enforcement rule (standard §9 marks it self-enforcement); nothing in the repo can refute or confirm it. |
| AG-06 | N/A | Harness/runtime permission rule about confirming risky operations; standard §9 marks it 'Runtime / harness enforcement. Not a code rule.' | No repo artifact governs this; not auditable from source. |
| AG-07 | N/A | Session-behavior rule (TaskCreate/TaskUpdate for ≥3-step work); self-enforcement per standard §9. | Not a checkable repo artifact. |
| AG-08 | N/A | Memory-discipline rule (federation-scoped vs session-scoped writes); self-enforcement per standard §9. | Not a checkable repo artifact. |
| AG-09 | N/A | Review-only rule about verifying sibling versions against the Codeberg registry rather than local dist/. tool.uv.index 'codeberg-mgf' (pyproject.toml:87-90) is the resolution target, consist | Review-only/self-enforcement; no refutable repo artifact, and the codeberg index pin shows no contradiction. |
| AG-10 | N/A | Review-only rule: standards drift an agent finds MUST become a PAPER, not a silent doc/code edit; standard §9 marks it review-only. | Not a checkable repo artifact; no evidence of silent doc-vs-code reconciliation commits. |
| AG-11 | ✅ | FEEDBACK.md present at repo root, giving this project a target file for project-specific friction; cross-cutting routing to mgf-common's FEEDBACK.md is the documented convention. No misroute | The routing target (this repo's own FEEDBACK.md) exists; rule is satisfied structurally and reviewer-enforced for routing. |
| AG-12 | ✅ | mgf-common is a hard runtime dep (pyproject.toml:43 'mgf-common>=0.41,<0.47'), so 'mgf-common agents --project' is installed wherever this repo is; project-scoped content lives in docs/claud | Refute attempt failed: because mgf-common is a dependency the --project briefing capability is available, and the project-scoped content lives in docs/claude/CLAUDE.md with AGENTS.md kept a thin pointer. [verify-upheld] |
| AG-13 | ✅ | This repo is a library (mgf-common consumer/sibling); FEEDBACK.md exists as the request channel for library changes. Commit history shows only pin-walks/regen/docs work on this repo, no cros | Consistent with the single-owner rule: this project consumes mgf-common via pin and files requests via FEEDBACK.md rather than editing the library. |
| AG-14 | ✅ | Commit d814eaf appends the per-MUST DOC-15 completeness enumeration in the same change that touches it; pin-walk commits (8b6e197, e07c2d6) update coupled surfaces (FEDERATION pointer, sync  | Observed commits propagate coupled surfaces in-change rather than deferring; no stale-dependent pattern found. |
| AG-15 | N/A | Empowerment-charter rule granting agents standing to push back/decline with rationale; standard §9 marks it review-only ('grants license, not a checkable artifact'). | Not a refutable repo artifact; license-grant rule with no required local file beyond the corpus (AG-16). |
| AG-16 | ✅ | No 'mgf-common[standards]' extra is declared anywhere in pyproject.toml — `grep -n standards pyproject.toml` returns nothing. The 'dev' extra (lines 55-76) pulls plain mgf-common (runtime, l | AG-16 requires depending on mgf-common[standards] where agents/maintainers run the federation CLI so the standards corpus is resolvable; this repo declares no such extra, so `mgf-common standards`/`design`/`federation`/`sync-prompt` would d — FIXED 2026-06-07: separate [standards] extra declares mgf-common[standards]>=0.46 (corpus resolvable to agents via .[standards] with Codeberg index; OUT of [dev] so CI pypi.org install is unregressed) |
| AG-17 | ✅ | docs/memory/MEMORY.md present (the project memory index). |
| AG-18 | ✅ | my_stuff/ git-ignored + .githooks/prepare-commit-msg present (auto-adds the Signed-off-by trailer). |
| AG-19 | N/A | no runtime auto-memory store for this project yet (~/.claude/projects/<slug>/memory/ absent) — nothing to VCS-track; binds only once such a store exists. |
| TM-01 | ✅ | UTC at boundaries — uses tz-aware `datetime`/UTC. |
| TM-02 | ✅ | ISO-8601/RFC-3339 wire format for datetimes. |
| TM-03 | N/A | no duration measurements with a wall clock (timeouts are not timed spans). |
| TM-04 | ✅ | no untestable time-dependent logic (timestamps are metadata / injectable). |
| TM-07 | N/A | UTC only; no IANA timezone-name usage. |
| TM-08 | ✅ | async sleeps use `asyncio.sleep`. |
| PF-01 | ⏳ | FLAG: perf tests use in-file thresholds, no recorded baseline. |
| PF-02 | ✅ | perf tests marked `@pytest.mark.perf`. |
| PF-03 | ⏳ | FLAG: no `tests/perf/baselines.json`. |
| PF-04 | N/A | re-baselining flow activates with recorded baselines. |
| PF-05 | ⏳ | FLAG: perf tests are plain-pytest timing, no statistical harness. |
| PF-07 | ✅ | perf failures surface the comparison numerically. |
| PF-08 | N/A | thresholds are relative-drop, not hardware-tier-sensitive. |
| OB-01 | N/A | no owned observability surface — consumes `mgf.common.observability` (OB rules bind the owner). |
| OB-02 | N/A | no owned observability surface — consumes `mgf.common.observability` (OB rules bind the owner). |
| OB-03 | N/A | no owned observability surface — consumes `mgf.common.observability` (OB rules bind the owner). |
| OB-04 | N/A | no owned observability surface — consumes `mgf.common.observability` (OB rules bind the owner). |
| OB-05 | N/A | no owned observability surface — consumes `mgf.common.observability` (OB rules bind the owner). |
| OB-07 | N/A | no owned observability surface — consumes `mgf.common.observability` (OB rules bind the owner). |
| OB-08 | N/A | no owned observability surface — consumes `mgf.common.observability` (OB rules bind the owner). |
| OB-09 | N/A | no owned observability surface — consumes `mgf.common.observability` (OB rules bind the owner). |
| OB-10 | N/A | no owned observability surface — consumes `mgf.common.observability` (OB rules bind the owner). |
| OB-11 | N/A | no owned observability surface — consumes `mgf.common.observability` (OB rules bind the owner). |
| NM-01 | ✅ | distribution name is hyphenated (NM-01). |
| NM-02 | ✅ | dotted import namespace `mgf.<sibling>` (NM-02). |
| NM-03 | ✅ | Codeberg slug hyphenated (NM-03). |
| GUI-01 | ✅ | imports no Qt at module level (GUI-01). |
| GUI-02 | N/A | no GUI (non-GUI library/CLI). |
| GUI-03 | N/A | no GUI (non-GUI library/CLI). |
| GUI-04 | N/A | no GUI (non-GUI library/CLI). |
| GUI-05 | N/A | no GUI (non-GUI library/CLI). |
| GUI-06 | N/A | no GUI (non-GUI library/CLI). |
| GUI-07 | N/A | no GUI (non-GUI library/CLI). |
| GUI-08 | N/A | no GUI (non-GUI library/CLI). |
| GUI-09 | N/A | no GUI (non-GUI library/CLI). |
| GUI-10 | N/A | no GUI (non-GUI library/CLI). |
| REL-10 | ✅ | federation member; participates in cohort-walk releases on a mgf-common pin break. |
| REL-11 | ✅ | released via the Phase A/B cohort-release flow. |
| REL-12 | N/A | binds the cohort Phase-A *agent's* pytest-denial handling, not a released sibling's code. |
| REL-13 | ✅ | releases pass the federation consistency gate (`mgf-fed registry --check`). |
| FB-05 | ✅ | cross-repo feedback flows through the `pending-feedback/<target>.md` outbox + the supervisor relay (`mgf-fed feedback`), never a direct edit (FB-05). |
