# Magogi Foundation Standards — Conformance Tracker (mgf-tele-core)

> **Status.** v0.1 — initial tracker. Created 2026-05-28 per the
> DOC-15 conformance-tracker sweep across federation siblings.
> **Scope.** mgf-tele-core's conformance to the standards at
> [mgf-standard/docs/standards/](https://codeberg.org/magogi-admin/mgf_common/src/branch/main/docs/standards/).
> **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:** Vendor-neutral telematics seam — the
`TelematicsProvider` device-session ABC, codec-agnostic AVL frame
types (`GeoPoint` / `DecodedAvlRecord` / `ReceivedPacket` /
`ParseStatus`), a typed `TelematicsError` hierarchy (all subclassing
`mgf.common.exceptions.AppError`), and a scripted
`MockTelematicsProvider`. Pure-Python under the `mgf.*` namespace; the
only runtime dependency is `mgf-common`. Foundation of the
`mgf-tele-*` family — per-vendor codecs depend on this, never the
reverse.

**Current version:** 0.1.1.

**Declared conformance level: L2** (per CFM-02). **2026-06-09: verified below L2 — 72 ✅ / 42 ⏳ / 104 N/A (63% of applicable); see §Z.**
mgf-tele-core pins `mgf-common>=0.41,<0.42` (see CHANGELOG /
pyproject for the current window).

**Premise note.** This is a *pure parsing + ABC* library: it defines
the seam vocabulary and a test double, not a running service. Several
standard families therefore have no premise here (see N/A below). The
families that *do* bite are DP (frozen frame types, UTC boundary), EH
(the `TelematicsError` hierarchy rooting in `AppError`), AP (the seam
surface contract), TS, DOC, REL — and, notably, **SC** (see §2.4).

**Applicable standards groups (rules audited):** DP, EH, LG, SC, CF, AP, TS, DOC, REL.

**N/A standards groups (rule premise doesn't apply to this
project's shape):**

- **GUI / UI standards** — N/A: no user interface; this is a library
  consumed by ingest code.
- **DB / persistence standards** — N/A: the seam holds no database;
  it hands `ReceivedPacket` / `DecodedAvlRecord` to the *consumer*,
  which owns persistence.
- **HTTP / web standards** — N/A: no HTTP surface; the provider takes
  an already-established `reader`/`writer` from the consumer's
  transport loop.
- **OP** — N/A: no runtime service / no operational footprint of its
  own.
- **DEP** — N/A: library, not a deployable.

(Logging is *not* N/A — LG applies, satisfied via mgf-common's
logging facilities rather than this package configuring its own.)

**Counts (2026-05-28 — initial tracker):**

| Priority | Count | Status |
|---|---|---|
| ✅ structurally conformant | (set on first depth audit) | (set on first depth audit) |
| 🚫 declined-with-rationale | 0 (initial tracker; populate as deferrals get filed) | — |
| ⏳ in-progress | (track from sibling's own RA/SH/PC trackers, when filed) | — |
| N/A | (rule premise doesn't apply — see §1 above) | — |

**Headline.** This tracker is the **rolling audit ledger** for
mgf-tele-core. It is scaffolded honestly: each family below is marked
*structurally conformant pending a first depth audit*. Drift over
time is the signal — the falsifiable per-rule evidence will live in
the sibling's own RA/SH trackers once those are filed.

---

## §2 Per-standard audit → superseded by §Z

> **2026-06-09:** the hand-written per-family prose is **superseded by the §Z evidence-based per-MUST
> audit** (file:line, refute-survived). Of 218: **106 ✅ · 7 ⏳ · 104 N/A · 1 declined**; applicable = 114;
> **63% evidenced**. Textbook DP-02 seam (project-owned ABC + shipped mock + a real method-set lock-in
> test), frozen frame types + frozen lock-in test, mypy --strict, typed error hierarchy, cancellation
> documented at the seam. The 63% reflects the missing publish chain (CI exists), a missing __version__
> (AP-13), and no PUBLIC_API surface yet. Only 3 genuinely deferred (EH-08, TS-28 perf, REL-01).

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

| Cluster | Rules | Count |
|---|---|---|
| **CLOSEABLE (release 0.1.6)** (publish chain + SCOPE + AP-13 __version__ + PUBLIC_API gen + buckets + closed-box contract + sbom) | AG-16, AP-10, AP-11, AP-13, AP-14, DOC-01, DOC-02, DOC-03, DOC-08, DOC-09, DOC-18, OP-03, PKG-01, PKG-03, PKG-04, PKG-05, PKG-09, PKG-12, PR-01, REL-03, REL-04, REL-06, REL-08, SC-18, SP-01, SP-02, SP-03, SP-04, SP-05, SP-06, TS-01, TS-20, TS-21, WF-03, WF-04, WF-05, WF-06, WF-07, WF-08 | 39 |
| **DEFERRED** (EH-08, TS-28 perf, REL-01 force-push) | EH-08, REL-01, TS-28 | 3 |


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

(none yet — initial tracker. 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

| Date | Auditor | Trigger | Findings |
|---|---|---|---|
| 2026-05-28 | initial tracker (DOC-15 sweep) | DOC-15 conformance-tracker requirement; this tracker created | initial tracker created — DOC-15 sweep; 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.
- [README.md](../../README.md) — declared level + the two-layer seam shape.
- [CHANGELOG.md](../../CHANGELOG.md) — release history.
- [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-09 depth audit** (16-family fan-out + adversarial refute on every ✅, hardened prompt + ruthless DP-02-seam/frozen-frames/typed-errors pass; ~32 agents + a 28-id re-run for 4 truncated families). Has CI + import-linter already; the textbook DP-02 seam (ABC + mock + real lock-in test). No 🚫-flood, no mislabels. **Mix: 72 ✅ · 42 ⏳ · 104 N/A · 0 🚫.** Replaces the prior scaffold.


### DESIGN_PRINCIPLES

| Rule | Status | Evidence | Notes |
|---|---|---|---|
| DP-01 | ✅ | pyproject.toml:148-161 [tool.importlinter] root_package=mgf.tele.core with a 'forbidden' contract (_frames/_provider/_errors ↛ mock); .woodpecker.yml lint step runs `lint-imports`. Ran  | [verify-upheld] Refute attempt failed. The one binding direction this pure seam lib has — core never importing its own test double — is contract-enforced and CI-linted, and I confirmed it passes. No UI exists to forbid; the sole r |
| DP-02 | ✅ | ABC: _provider.py:80 `class TelematicsProvider(ABC)` with 4 @abstractmethod (open_session/receive_packet/send_command/close_session, :85-122). Mock: mock.py:42 `MockTelematicsProvider(T | [verify-upheld] Refute attempt failed — I scrutinised the lock-in test specifically. It is REAL: it pins the exact abstract-method set against __abstractmethods__, so adding/removing an abstractmethod breaks deliberately and force |
| DP-03 | ✅ | All cross-boundary types are `@dataclass(frozen=True, slots=True)`: _frames.py GeoPoint(:51), DecodedAvlRecord(:64), ReceivedPacket(:86); _provider.py SessionHandle(:43), TrackerCommand | [verify-upheld] Refute attempt failed. I read every dataclass decorator in src/: all six carry frozen=True, slots=True. ReceivedPacket uses field(default_factory=list) for `records` (a mutable default done correctly) and the froze |
| DP-04 | ✅ | pyproject.toml:81-96 [tool.mypy] strict=true over packages=['mgf.tele.core'] with disallow_untyped_defs/incomplete_defs/no_implicit_optional/warn_return_any. .woodpecker.yml typecheck s | [verify-upheld] Refute attempt failed — I executed mypy and it passed clean on all 5 source files. All public signatures annotated; no `Any` without justification observed. mypy --strict configured, CI-gated, and verified passing. |
| DP-05 | ✅ | Tests drive MockTelematicsProvider with scripted batches + MagicMock reader/writer (test_provider_and_mock.py, test_reliability.py) — no network/daemon/creds. filterwarnings=['error'] ( | [verify-upheld] Refute attempt failed. The hard MUSTs (no real daemon, no creds, no network; mocks via the provider ABC) are fully met — I confirmed every test uses the in-memory mock + MagicMock streams. Layout is flat tests/test |
| DP-06 | ✅ | Reliability: dedicated test_reliability.py drives full lifecycle, exhaustion, idempotent close, independent-session isolation, error-hierarchy completeness incl. the no-spurious-http_st | [verify-upheld] Refute attempt failed. For a pure-domain seam lib the four concerns are addressed in design and tests: reliability has a dedicated module, error reporting is the typed hierarchy, security is the bandit/CVE/secret-s |
| DP-07 | ✅ | Every public class/function carries intent+invariants docstrings: TelematicsProvider + all 4 abstractmethods (_provider.py:80-122 — open_session states who owns the socket close; receiv | [verify-upheld] Refute attempt failed — I read every docstring. They consistently state intent + invariants (forensic envelope, idempotent close, opaque-handle contract, raw-bytes placeholder rationale in the mock) with no 'return |
| DP-08 | ✅ | README 'The two-layer shape' diagram + prose document the swap recipe: a new vendor is a new mgf-tele-<vendor> package shipping a codec + Provider(codec), depending on this core, never  | [verify-upheld] DP-08 is a SHOULD. The replaceability story (how to add/swap a vendor provider) is documented adjacent to the abstraction in both README and the _provider module docstring. Met. |
| DP-09 | ✅ | _provider.py:18-21 module docstring: 'Per rule DP-09, long-running sessions take cancellation via the concrete provider's constructor (different vendors have different cancellation need | [verify-upheld] Refute attempt failed — confirmed no threading.Event/thread-global anywhere in src/. The ABC deliberately and explicitly delegates cancellation to the concrete provider's constructor with a documented rationale rat |
| DP-10 | N/A | Single runtime dependency (mgf-common, pyproject.toml:30-32); no keyring→file or any backend-selection fallback path anywhere in the 5 source modules. The mock is not a runtime fallback | Adjudicated fresh (not in the provided ✅ set). DP-10 binds only when a fallback path exists (e.g. keyring→encrypted file). This pure seam lib has no fallback backend to make queryable or log at startup. Not applicable to this shap |
| DP-11 | N/A | grep for `create_task`/`asyncio.create_task` in src/ returns no detached-task creation. The async surface is the TelematicsProvider ABC's abstract coroutine methods + the mock's awaitab | Adjudicated fresh (not in the provided ✅ set). DP-11 binds every `asyncio.create_task` to retention; with zero task creation in this library there is nothing to own. The async methods are caller-awaited coroutines, not detached ta |
| DP-12 | ✅ | mock.py:65 `SessionHandle(imei=..., opened_at=datetime.now(UTC))` — explicit UTC. conftest.make_record uses datetime.now(UTC). _frames.py:14-15 + DecodedAvlRecord.ts document UTC-at-bou | [verify-upheld] Refute attempt failed — confirmed the only datetime construction site (mock open_session) uses tz-aware UTC, and grep found no naive datetime.now()/utcnow() in src/. DTZ lint mechanically forbids naive datetimes. F |
| DP-13 | N/A | The library owns no external resources in production code: the ABC's open_session docstring (_provider.py:96) explicitly states 'the supervisor owns the underlying socket close' — the p | Adjudicated fresh (not in the provided ✅ set). DP-13 binds owned external resources (files, sockets, subprocesses, locks) to deterministic release. This seam layer owns none — socket ownership is explicitly assigned to the caller/ |

### ERROR_HANDLING

| Rule | Status | Evidence | Notes |
|---|---|---|---|
| EH-01 | ✅ | src/mgf/tele/core/_errors.py:12,25 — TelematicsError(AppError) with 6 subclasses (MalformedPacketError/ChecksumError/UnsupportedCodecError/MalformedHandshakeError/UnknownTrackerError/Se | [verify-upheld] Refute attempt: searched every raise site — mock.py:78 (MockExhaustedError, rooted at TelematicsError→AppError) and mock.py:95 (NotImplementedError). NotImplementedError is the conventional unbuilt-method sentinel, |
| EH-02 | ✅ | _provider.py:93-110 — open_session docstring requires MalformedHandshakeError/UnknownTrackerError on rejection; receive_packet docstring requires SessionClosedError for socket-level fai | [verify-upheld] Refute attempt: grepped the source for any except/translation seam (grep showed zero `except` and zero `from e` in runtime code) — confirming there is NO third-party boundary inside THIS package to translate at. As |
| EH-03 | N/A | No exception translation / re-raise of a third-party cause exists in the package's runtime code. grep across src/mgf/tele/core found zero `except` blocks and zero `from e` chaining (onl | EH-03 governs HOW a translated exception chains its original cause (`raise NewError(...) from original`). This package contains no translation seam in its runtime code (it is the definer side; the actual try/except-with-`from e` r |
| EH-04 | N/A | No entry point exists: pyproject.toml has [project] + [project.optional-dependencies] but NO [project.scripts]/console_scripts/gui entry. The package is a pure-domain seam library (ABC  | EH-04 ('every ENTRY POINT MUST install a top-level handler') applies to processes that own an entry point — CLI (_run_and_translate_exceptions), process (sys.excepthook), threads, asyncio loop, Qt. A library that is imported has n |
| EH-05 | N/A | No crash reporter and no entry point in the package (no [project.scripts]; runtime dep is only mgf-common, not mgf.common.observability). The package never runs as a process — it is imp | EH-05 (unhandled exceptions MUST produce a local crash report + optional remote forward) is an entry-point/process concern, discharged by the consuming application (which SHOULD use mgf.common.observability.report_now per §6). A p |
| EH-06 | N/A | No GUI: the package ships only an ABC, frozen frame dataclasses, a typed error hierarchy, and a scripted async mock (5 modules in src/mgf/tele/core/). No QThread/CoreWorker/Qt import an | EH-06 governs GUI worker threads (catch every exception, forward via error(str) signal). This is a vendor-neutral domain seam library with no GUI surface. N/A per the stated carve-out (no GUI/CLI/service). |
| EH-07 | ✅ | grep -rn 'except Exception' over src/mgf/tele/core/ returns ZERO hits. The package contains no `except` blocks at all in its runtime code (the only try-shaped logic is the `if not self. | [verify-upheld] EH-07 forbids `except Exception:` outside cleanup/best-effort-observer paths. The library has no broad-except anywhere, so the rule is satisfied with no exception needed. Vacuously upheld — there is no construct th |
| EH-08 | ⏳ | _errors.py:25-51 — every TelematicsError subclass is a bare `class X(TelematicsError): """docstring"""` with NO __init__ and NO machine-readable fields. mock.py:36 MockExhaustedError is | Refute-of-presumption: there is a real, defensible domain case for some of these to carry fields — ChecksumError could carry the computed-vs-declared CRC; MalformedHandshakeError/UnknownTrackerError could carry the offending IMEI; |
| EH-09 | N/A | No user-facing message surface: no CLI/GUI rendering (no [project.scripts], no click/echo, no GUI). Exception messages here are diagnostic strings for consumers/operators (e.g. mock.py: | EH-09 ('messages SHOWN to users MUST end in an actionable next step') and its §12.7 pinning-test apply to user-facing rendered messages (CLI output / GUI dialog). A pure seam library produces no user-facing output; its exception s |
| EH-10 | N/A | No best-effort observer / fan-out loop exists in the package. The five modules are an ABC, frozen frame types, a typed error hierarchy, and a scripted mock — no hook executor, scheduler | EH-10 governs the never-raises invariant for best-effort observer code (catch broadly, log WARNING, return bool, continue). No such construct exists in this seam library. N/A. |
| EH-11 | N/A | No retry logic anywhere: grep for retry/backoff in src found only a docstring mention (_provider.py:50 notes a concrete provider MAY carry 'retry budgets' in its SessionHandle subclass) | EH-11 (exponential backoff + full jitter + finite cap + audit log) governs retry of external calls. This package makes no external calls and contains no retry helper; retry is a documented concrete-provider concern (DP-09). Nothin |
| EH-12 | N/A | The only idempotent operation in the package is the ABC's close_session, documented idempotent (_provider.py:122) and tested (test_reliability.py:99-116, test_provider_and_mock.py:70-74 | EH-12 scopes to 'operations against external systems with multi-attempt cost (writes, sends)' (line 26) that must be idempotent under retry. This seam library performs no such external write/send — the codec/consumer owns the sock |
| EH-13 | N/A | No external call that can amplify upstream load exists in the package (runtime dep mgf-common only; no socket/HTTP/SDK call — those live in the downstream codec). No circuit breaker and | EH-13 (bound upstream-amplifying load; circuit breaker as canonical mechanism) applies to packages that make external calls against a struggling upstream. This pure seam library makes no external calls; the amplification surface l |

### LOGGING

| Rule | Status | Evidence | Notes |
|---|---|---|---|
| LG-01 | N/A | grep for logging/getLogger/LOG. across src/mgf/tele/core/{_provider,_frames,_errors,mock,__init__}.py and tests/ returns nothing (exit 1, zero matches). No module acquires or uses a log | LG-01 binds modules that EMIT log records ('every module MUST acquire its logger via getLogger(__name__)... no bare logging.info'). This is a pure-domain seam library: an ABC (_provider.py, signatures only), frozen frame dataclass |
| LG-02 | N/A | No __main__/CLI/app.run/service entry point exists; src/ is 5 library modules with no setup_logging call (grep found none). pyproject ships no console_scripts (library package, mgf-tele | LG-02 binds an APPLICATION with an entry point ('configure logging in exactly one place per entry point... emit JSON when stdout is not a TTY'). A pure-domain seam library has no entry point and MUST NOT configure root logging (th |
| LG-03 | N/A | No log records are emitted anywhere (no formatter, no log calls). _add_otel_context lives in mgf.common.observability per the standard's note, not here. | LG-03 ('every log record MUST carry trace_id/span_id... the standard formatter adds these automatically') binds record emission. With zero records emitted and no formatter owned here, there is no record to carry trace context. The |
| LG-04 | N/A | No formatter or sink is defined in this library; Redactor lives in mgf.common.observability per the standard's §0 note. grep found no logging code. | LG-04 ('sensitive fields MUST be redacted by the formatter before any sink sees them') binds a library that owns a formatter/sink path. This seam library owns neither — it emits no records and ships no sink. Redaction is the consu |
| LG-05 | N/A | No ERROR-level log calls exist (grep for .error(/.exception( returns nothing). The error path here is RAISING typed exceptions (mock.py:78 raise MockExhaustedError; mock.py:95 raise Not | LG-05 ('ERROR-level logs MUST include exc_info') binds code that logs at ERROR. This library raises typed errors (the EH layer) for the consumer to catch and log; it never logs them itself. With no ERROR log sites the rule has no  |
| LG-06 | N/A | No emitting code and no sink configuration anywhere in src/. Library package (no entry point) per pyproject. | LG-06 ('logs MUST reach a searchable aggregator; console-only is non-compliant in production') binds the deployable application that owns sink wiring. A pure-domain library imported by services/codecs neither emits nor configures  |
| LG-07 | N/A | Matrix row: LG-07 applies to 'gui-app' only. No GUI/PySide6 anywhere; this is a headless seam library (5 src modules, runtime dep mgf-common only). | LG-07 ('GUI apps MUST ship a log-viewer dialog') is explicitly gui-app-scoped in the per-kind compliance matrix (§Rules box). This library has no GUI. Premise does not bind. |
| LG-08 | N/A | No log calls exist (grep returns nothing), so there are no message strings to format lazily. The f-strings present (mock.py:77, mock.py:91-94) build EXCEPTION messages, not log messages | LG-08 ('log messages MUST use lazy %-style formatting, NOT f-strings') binds log call sites. There are none. The f-strings in mock.py construct exception-message text (legitimate per EH style — exception messages are eager by natu |
| LG-09 | N/A | No log calls and no extra={} usage anywhere (grep found nothing). | LG-09 ('structured fields MUST be passed via extra={}') binds log emission. With zero log sites there is no message into which fields could be concatenated. Premise does not bind. |
| LG-10 | N/A | Matrix row: LG-10 applies to 'service' kind. No systemd timer/daemon/background-task entry point; library package with no entry point. | LG-10 ('headless services MUST configure logging at their entry point with JournalHandler') is service-scoped in the per-kind matrix. A pure-domain seam library is not a service and has no entry point. Premise does not bind. |
| LG-11 | N/A | The seam methods (_provider.py:86-122 open_session/receive_packet/send_command/close_session) are ABSTRACT (only signatures + docstrings; abstractmethod). The mock's implementations (mo | LG-11 ('operation start/end MUST be logged for any function >=100ms OR crossing a process/network/storage boundary; short pure-Python helpers are exempt') binds CONCRETE boundary-crossing implementations. The real boundary-crossin |
| LG-12 | N/A | No log emission anywhere (grep found no log calls). | LG-12 ('log emission MUST be cheap, <=100us per record; heavy work in the handler') binds emit sites and handler implementations. This library emits nothing and ships no handler. Premise does not bind. |
| LG-13 | N/A | No log call sites, no inner-loop/per-event-callback log emission (grep found nothing). receive_packet (mock.py:69) pops one batch per call and does not log. | LG-13 ('high-frequency log sites MUST use rate-limiting/sampling') binds high-frequency log emission. The per-packet receive path here emits no logs (and is the mock anyway); the production per-packet logging discipline binds the  |
| LG-14 | N/A | No log records emitted and no correlation-context propagation code; no contextvars usage (grep found none). SessionHandle (_provider.py:43-57) carries imei/opened_at as data, not as a l | LG-14 ('custom correlation context MUST propagate through contextvars.ContextVar; the standard formatter promotes registered contextvars to log fields') binds emitting applications that set/promote correlation context. A pure-doma |
| LG-15 | N/A | No INFO+ records emitted at any lifecycle/security/boundary event (grep found no log calls). No docs/reference/EVENTS.md exists (find over the repo shows no EVENTS.md). The lifecycle ev | LG-15 ('every INFO+ record at a notable lifecycle/security/boundary event MUST carry a stable event field; names documented in EVENTS.md') binds records this library would emit. It emits none — the seam expresses lifecycle/boundar |
| LG-16 | N/A | No WARNING/ERROR records emitted (grep for .warning(/.error(/.exception( returns nothing). Failure information is carried instead by typed exceptions (_errors.py:25-51, seven typed subc | LG-16 ('every WARNING and ERROR record MUST answer WHAT/WHY/HOW') binds WARNING/ERROR log records. This library produces zero such records; its failure surface is typed exceptions (the EH family's concern) and a parse_status/parse |
| LG-17 | N/A | SHOULD, and no ERROR records exist (grep found no log emission). No formatter owned here to compute a fingerprint; the formatter lives in mgf.common.observability per the standard's §0  | LG-17 ('every ERROR record SHOULD carry a stable fingerprint; the formatter computes it automatically when exc_info is set') binds ERROR record emission and the formatter that owns fingerprint computation. This library emits no ER |

### CONFIGURATION

| Rule | Status | Evidence | Notes |
|---|---|---|---|
| CF-01 | N/A | src/mgf/tele/core/ (5 modules: _provider.py, _frames.py, _errors.py, mock.py, __init__.py). grep for os.environ/getenv/BaseSettings/BaseAppSettings/pydantic_settings/yaml across src/ an | CF-01 is scoped 'consumer-owned-config' (CONFIGURATION.md:23). This library owns no config schema — there is no BaseSettings subclass and no module reads env vars or a config file. Premise does not bind a pure telematics-seam libr |
| CF-02 | N/A | No Settings class, no settings_customise_sources, no load_settings; the library's only runtime dep is mgf-common (pyproject.toml:30-31) and it does not subclass BaseAppSettings (verifie | CF-02 (precedence chain CLI>env>.env>file>defaults) presupposes a layered-source Settings object. There is none here. Although CF-02 is tagged 'all', 'all' means all consumers WITH a config; a seam library with no config has nothi |
| CF-03 | N/A | No config schema and no version field anywhere in config sense; the only versioning is the package's distribution version (0.1.5). | CF-03 is 'consumer-owned-config' (CONFIGURATION.md:25). No schema means no schema-version field and no migration chain. Premise unbound for a library with no on-disk config. |
| CF-04 | N/A | No config-write path exists; grep found no yaml/write_text/atomic_write/save_settings in src/ or tests/. The frame types are frozen dataclasses (_frames.py:51,64,86) — read-only domain  | CF-04 (atomic 0o600 writes + lazy path expansion) is 'consumer-owned-config' (CONFIGURATION.md:26). This library writes no config or state file. Premise unbound. |
| CF-05 | N/A | No config file and no secrets: the library handles AVL telematics frames and device-session abstractions only; no Vault, no credentials, no API keys in src/. | CF-05 (secrets in a Vault, not config) is tagged 'all', but its premise is a consumer that handles secrets/config. This seam library stores no secrets and ships no config file into which a secret could leak. Premise unbound. |
| CF-06 | N/A | No pydantic Settings model and no YAML loader (no extra='forbid' surface) anywhere in src/; only frozen domain dataclasses in _frames.py and the ABC in _provider.py. | CF-06 (unknown-key rejection on config load) is 'consumer-owned-config' (CONFIGURATION.md:28). There is no config file to load and no schema to reject unknown keys against. Premise unbound. |
| CF-07 | N/A | No sub-config / satellite files (hooks/schedules/profiles) exist; the library is 5 source modules with no file-loading code. | CF-07 (satellite config files follow the same typed+atomic+versioned shape) is 'consumer-owned-config' (CONFIGURATION.md:29). No satellite config files exist. Premise unbound. |
| CF-08 | N/A | No Settings object to load-once-at-entry-point; no module-global singleton config; library is consumed by importing the ABC/frames/errors, not by a process entry point that builds Setti | CF-08 (load Settings once at entry point, inject by constructor) is 'consumer-owned-config' (CONFIGURATION.md:30). A seam library has no Settings object and no entry point. Premise unbound. |
| CF-09 | N/A | No CLI: grep found no argparse/click/sys.argv in src/. The library is a pure-domain SEAM (ABC + frozen frames + errors + scripted mock), explicitly no GUI/CLI/service per the audit shap | CF-09 (a --config flag honouring XDG/OS conventions) is 'consumer-owned-config' and presumes a CLI. This library ships no command surface. Premise unbound (same disposition as a non-CLI library). |
| CF-10 | N/A | tests/ exercise the ABC/mock method-set lock-in (test_provider_and_mock.py:17 _EXPECTED_ABSTRACTS) and frame freezing (test_frames.py:37 test_frames_are_frozen). There is no Settings cl | CF-10 (tests construct Settings with explicit values, no env leakage) is tagged 'all' but presumes a Settings object exists to test. There is none. The tests correctly test the seam, not config. Premise unbound. |
| CF-11 | N/A | No config fields exist, hence no field-rename/alias concern; no Field(alias=)/validation_alias anywhere in src/. | CF-11 (rename config fields via alias + deprecation) is 'consumer-owned-config' (CONFIGURATION.md:33). No config schema, no fields to rename. Premise unbound. |
| CF-12 | N/A | No config backend variants: the provider seam (_provider.py:80 TelematicsProvider ABC) is a runtime polymorphism seam realised via the ABC + mock impl, NOT a config-level discriminated  | CF-12 (mutually-exclusive backend variants modelled as a discriminated union in config) is tagged 'all' but presumes a config field with backend variants. The library's backend selection (mock vs vendor codec) happens at import/co |

### SECURITY_STANDARD

| Rule | Status | Evidence | Notes |
|---|---|---|---|
| SC-01 | ✅ | .woodpecker.yml:69-73 runs gitleaks v8.30.1 `gitleaks detect --source . --no-banner --redact` over working tree + history on push/PR/manual; grep -rniE for password/secret/token/api_key | [verify-upheld] Tried to refute: the library handles zero credentials (pure telematics seam — no vault, no auth, no keys), and the one 'token' hit is SessionHandle's docstring describing an opaque session token, not a secret liter |
| SC-02 | N/A | grep -rniE subprocess/shell=True/os.system over src/ returns nothing; the 5 modules (_frames/_provider/_errors/mock/__init__) are pure dataclasses + ABC + exception classes with no proc | A pure-domain seam library invokes no subprocess. The argv-only rule has no surface here. ruff S603 is enabled (pyproject:70) as a standing guard if subprocess is ever added. |
| SC-03 | N/A | grep over src/ finds no yaml./pickle/json.loads; the library deserialises nothing — frames are constructed in-process by codecs, not loaded from YAML/pickle. | No deserialization surface in the seam. ruff lints would flag yaml.load if added. N/A. |
| SC-04 | N/A | No file-write code in src/ (no open(...,'w'), no atomic_write, no Path.write_text); the library owns no on-disk state. | A pure in-memory seam writes no private-data files. The 0o600/atomic-write rule has no call site. |
| SC-05 | N/A | grep for md5/sha1/random./hashlib/cryptography/secrets over src/ returns nothing; no cryptographic primitives anywhere in the 5 modules. | The seam performs no crypto. ruff S-rules + the federation md5/sha1 grep would catch a regression. N/A. |
| SC-06 | N/A | No outbound connections in src/ — no httpx/requests/ssl/paramiko/socket.connect; the provider ABC only declares abstract async methods (concrete socket I/O lives in the vendor-codec pac | The seam opens no TLS connection itself; the production transport is the vendor codec (mgf-tele-teltonika). TLS-verify enforcement applies there, not here. N/A for mgf-tele-core. |
| SC-07 | N/A | No external calls in src/ (no httpx/subprocess/SSH/DB). The provider docstrings (_provider.py:98-101) note sessions read from a socket but the concrete read+timeout lives in the codec i | The ABC declares method signatures only — no boundary call to attach a timeout to. The timeout obligation falls on the concrete provider (vendor codec) and the consumer's session loop, documented in SECURITY.md. N/A for the seam l |
| SC-08 | ✅ | The codec-agnostic frame types are typed+frozen dataclasses (_frames.py:51-111): GeoPoint/DecodedAvlRecord/ReceivedPacket with explicit field types; ParseStatus is a Literal allow-list  | [verify-upheld] Tried to refute on 'untrusted AVL input bounds': the seam does not itself parse wire bytes (the vendor codec does), so byte-length bounding is the codec's job, not this package's. What SC-08 requires AT THIS LAYER  |
| SC-09 | N/A | No log records emitted anywhere in src/ (no logging import, no LOG.* calls); the seam emits no logs and carries no sensitive fields. | Redaction applies to a formatter before a log sink; this library has no logging surface. mgf-common's Redactor is the federation mechanism for consumers. N/A. |
| SC-10 | ✅ | uv.lock committed at repo root (187547 bytes, confirmed via wc -c); .woodpecker.yml:60-67 runs `pip-audit --strict` in a dedicated vuln-scan step on push/PR/manual; pyproject.toml:46-49 | [verify-upheld] Tried to refute: the lockfile is present and non-trivial, and pip-audit --strict is a real CI gate on every event (not just main). Triage policy is documented in SECURITY_STANDARD §10.2; no outstanding findings obs |
| SC-11 | N/A | Typed errors in _errors.py are message-only subclasses of AppError with no secret-bearing args; there is no translation seam wrapping an external library's exception (no SSH/subprocess/ | SC-11 governs scrubbing secrets out of tracebacks at a translation seam. The seam handles no secrets and wraps no secret-bearing upstream exception, so there is nothing to scrub. The one place that could have leaked (mock send_com |
| SC-12 | ✅ | SECURITY.md at repo root: Supported-versions table (:18-21, 0.1.x ✅), private Reporting channel (email bassam@magogi.org + Codeberg private advisory, :24-31), What-to-include (:34-42, t | [verify-upheld] Tried to refute against the §11.1 template: all four required elements (supported versions, security contact, embargo expectation, disclosure timeline) are present and tailored to the telematics-seam threat surface |
| SC-13 | N/A | No cryptographic keys anywhere in src/ (no KEY=, no embedded key material, no KDF). grep confirmed no crypto surface. | The seam stores/derives no keys. N/A. |
| SC-14 | N/A | No authentication boundary in the library. UnknownTrackerError/MalformedHandshakeError (_errors.py:41-46) are typed signals a codec raises, but the seam implements no credential check,  | SC-14 governs an auth verifier's enumeration/lockout behaviour. mgf-tele-core defines error TYPES but performs no authentication itself — the handshake/identity decision is the concrete provider's + consumer registry's responsibil |
| SC-15 | N/A | No filesystem path construction from external input in src/ (no Path(...) joins, no resolve, no os.open); the seam touches no filesystem. | Directory-traversal protection requires a path built from external input; the library builds none. N/A. |
| SC-16 | N/A | grep for sudo/setuid/chmod/capability/privileged over src/ returns nothing; pure-domain code requests no privilege. | No privileged operation surface. N/A. |
| SC-17 | N/A | No logging in src/ (no logging import, no audit=true records); the seam emits no security-relevant action records because it performs no vault/subprocess/SSH/config-write/auth action. | SC-17 requires audit records for security-relevant ACTIONS the application takes; this library takes none (it declares types + an ABC). The concrete provider/consumer emits session/auth audit records. N/A for the seam. |
| SC-18 | ✅ | Hatchling pure-Python build (pyproject:1-3, hatchling>=1.21, no compiled extension) is inherently reproducible from a tagged commit using only declared deps. uv.lock pins the dependency | [verify-refuted: there is no upheld ✅ to defend — this id was not in the ✅ set, adjudicated fresh] A pure-Python wheel IS buildable from source, but SC-18's mechanical promise (CI builds + checksums match published; build metadata — FIXED 2026-06-09: .woodpecker sbom step (reproducible CycloneDX) |

### TESTING

| Rule | Status | Evidence | Notes |
|---|---|---|---|
| TS-01 | ⏳ | tests/ is FLAT: test_provider_and_mock.py, test_reliability.py, test_errors.py, test_frames.py, test_smoke.py, conftest.py — no tests/unit/ tree mirroring src/mgf/tele/core/{_provider,_ | TS-01 MUST: tests/ mirrors src/ 1:1 with tests/unit/<sub>/test_<mod>.py and CI MUST lint that no source file lacks a mirror beyond a documented allow-list. The suite is comprehensive but lives flat, not in the mirrored tests/unit/ |
| TS-02 | ✅ | [verify-upheld] tests/test_provider_and_mock.py + tests/test_reliability.py drive MockTelematicsProvider only, calling open_session(MagicMock(),MagicMock()); no socket/network/credentia | Refute attempt failed: the entire suite is in-memory against the scripted mock, reaching I/O only through the provider ABC (DP-02). Upheld. |
| TS-03 | ✅ | [verify-upheld] tests/conftest.py defines a function-scoped `record` fixture + a pure make_record() factory; no module-level mutable state. test_reliability.py::test_independent_session | Refute attempt failed: a pure-seam suite touching no process-global state holds isolation by construction, and an explicit independence test pins it. Upheld. |
| TS-04 | ✅ | [verify-upheld] pyproject.toml [tool.pytest.ini_options] filterwarnings = ["error", "default::mgf.common._warnings.MgfDeprecationWarning", "default::pytest.PytestUnraisableExceptionWarn | Refute attempt failed: filterwarnings=["error"] is set; the two default:: relaxations are the rule-sanctioned per-category form. Upheld. |
| TS-05 | ✅ | [verify-upheld] pyproject.toml addopts (lines 103-108) includes "--strict-markers" and "--strict-config". | Refute attempt failed: both flags present. Upheld. |
| TS-06 | ✅ | [verify-upheld] pyproject.toml [tool.coverage.run] source=["src/mgf"] branch=true; [tool.coverage.report] fail_under=90 (line 139) show_missing. .woodpecker.yml test-3.12 runs pytest -- | Refute attempt failed: ≥80% gate present (set at 90), enforced on the 3.12 CI job, and assertions exercise real behaviour (frames, mock lifecycle, error catchability) — no tautological-shim coverage. Upheld. |
| TS-07 | ✅ | [verify-upheld] tests/test_errors.py parametrizes the 6 concrete TelematicsError subclasses (raise/catch + category). tests/test_reliability.py: test_subclass_constructs_from_message_an | Refute attempt failed: message round-trip + args preservation asserted for every subclass; the no-http_status pin covers field-absence. No copyable mutable fields exist, so the copy-not-alias clause is vacuously satisfied. Upheld. |
| TS-08 | N/A | No EH-02 third-party-error translation seam exists in this repo. SessionClosedError's docstring describes a 'typed translation of an incomplete-read/connection-reset at the socket layer | TS-08 applies to translation seams (rule EH-02). This pure seam library defines the typed targets but performs no third-party-error translation, so there is no translation seam to test. Not applicable. |
| TS-09 | N/A | No EH-10 best-effort observer / callback loop exists anywhere in src/mgf/tele/core/ (4 source modules: frozen frame records, the provider ABC, the typed errors, and the scripted mock).  | TS-09 requires a test for every best-effort observer (rule EH-10). This library has none. Not applicable. |
| TS-10 | N/A | src/ has no security-relevant mechanical surface to pin: no subprocess/shell, no yaml/pickle/XML parsing, no redaction-of-secrets path, no untrusted-input bounds. Frames are plain froze | TS-10 binds security MUSTs (SC-01..18) 'where mechanically possible'. No SC rule has an in-repo mechanical surface here (the parse/bounds surface lives in the codec), so there is nothing to pin. Not applicable for this seam librar |
| TS-11 | N/A | No GUI: pure-domain seam library (no PySide6/Qt, no worker threads, no pytest-qt dep). Confirmed by the SHAPE carve-out (no GUI/CLI/service). | TS-11 governs GUI worker tests (rule EH-06). There is no GUI. Not applicable. |
| TS-12 | ✅ | src/mgf/tele/core/_provider.py:86,100,113,121 + src/mgf/tele/core/mock.py:60,69,88,97 define the 4 coroutines (open_session/receive_packet/send_command/close_session) on the TelematicsP | Async code exists and is tested with pytest-asyncio. Every coroutine on the ABC and the mock has at least one async test that awaits it — no untested coroutine (no defect). asyncio_mode=auto gives per-test function-scoped event lo |
| TS-13 | N/A | No round-trip code in-repo: no parse/serialise, encode/decode, or save/load. _frames.py defines frozen records; there is no codec (bytes→record) here — that is the vendor package. No _s | TS-13 mandates property tests for code that round-trips data. The seam owns the frame vocabulary but does no round-tripping; the round-trip surface lives in the per-vendor codec. Not applicable here. |
| TS-14 | N/A | No performance budget is owned by this seam library — there is no PERFORMANCE.md budget and no perf-sensitive production path it constrains (frame construction + a deque pop). The `perf | TS-14 requires a benchmark only where a performance budget exists to pin. This library defines no such budget, so there is no production path to benchmark. Not applicable (perf marker defensive-registration is satisfied under TS-1 |
| TS-15 | N/A | No real backend exists to smoke against: the production implementation is a separate per-vendor package (mgf-tele-teltonika) running over real TCP/UDP to physical trackers. This library | TS-15 governs opt-in smoke tests against real external backends. This seam has no real backend in its own surface. Not applicable. |
| TS-16 | ✅ | [verify-upheld] test_provider_and_mock.py::test_abstract_method_set_is_pinned compares TelematicsProvider.__abstractmethods__ to a named frozenset _EXPECTED_ABSTRACTS (self-describing s | Refute attempt failed: failures are either named-set comparisons (readable diffs) or carry diagnostic context (the imei). Upheld. |
| TS-17 | ✅ | [verify-upheld] tests/conftest.py holds the only shared fixture (`record`) + the make_record factory at the test root, discoverable via the conftest hierarchy. `from tests.conftest impo | Refute attempt failed: the shared fixture lives in tests/conftest.py and is injected; make_record is an ordinary importable factory (not a fixture), so the no-cross-import rule is not violated. Upheld. |
| TS-18 | ✅ | [verify-upheld] `slow` marker registered (pyproject line 130, tier-3) and default-excluded via addopts -m '... and not slow' (line 107). I measured the full suite at 0.07s for 49 tests  | Refute attempt failed: marker registered + default-excluded; no slow test exists. Defensive registration satisfies the rule. Upheld. |
| TS-19 | ✅ | [verify-upheld] pyproject.toml markers (lines 117-131) declares every used marker with a tier annotation: smoke(tier-0, used by test_smoke.py pytestmark) + contract/property/regression/ | Refute attempt failed: registration is comprehensive and tier-annotated; both marker axes present; slow registered defensively. Upheld. |
| TS-20 | ⏳ | tests/ contains no tests/unit/, tests/integration/, tests/e2e/, or tests/smoke/ directories — all five test files sit flat at the tests/ root. The smoke tests (test_smoke.py) apply pyte | TS-20 MUST: tests partitioned across the four canonical directories (unit/integration/e2e/smoke). The suite is flat; only the marker axis is in place (TS-19/TS-22), not the directory partition. Gap. |
| TS-21 | ⏳ | A marked smoke layer exists in substance — tests/test_smoke.py (pytestmark=pytest.mark.smoke, tier-0, recorded at 0ms in run.jsonl) verifies (a) the package imports, (b) a SUBSET of __a | TS-21 MUST: every published library has a smoke layer (tests/smoke/) verifying package import + EVERY name in __all__ reachable + shortest happy path of every public entry. The smoke tests exist, are marked, and run fast (<100ms), |
| TS-22 | ✅ | [verify-upheld] mgf-test-supervisor>=0.1.2,<0.2 is a dev dep (pyproject line 40, sourced from codeberg-mgf index, lines 51-53). Every registered marker is tier-annotated (lines 118-130) | Refute attempt failed: the supervisor is depended-on, markers are tier-mapped per the canonical MARKER_TIER, and tiered records exist. Upheld. |
| TS-23 | ✅ | mgf-test-supervisor (the canonical reference path) is the dev dep and IS the run harness: .gates/last-run/ holds run.jsonl (per-test JSONL), junit-0000.xml, summary.md ('mtest run summa | TS-23 MUST: a harness that survives+structures pytest crash/hang/signal-death (subprocess model, bounded hang + thread dump, single-file context, no bootstrap circularity). The published supervisor — the canonical reference path — |
| TS-24 | ✅ | .gates/last-run/run.jsonl is one JSON object per line (49 records). Each record carries the DoctorFinding mirror (code/severity/summary/detail/why/remediation) PLUS the testing fields ( | TS-24 MUST: per-test records as one JSON object per line at .gates/last-run/run.jsonl, schema mirroring DoctorFinding + the testing-specific fields, schema_version mandatory, via mgf.test_supervisor.records. All present. Met. |
| TS-25 | ✅ | .gates/quarantine.json exists (content {} — empty because no test has flaked) with the 0600 perms the atomic-write persistence uses. mgf-test-supervisor (which provides mgf.test_supervi | TS-25 (L2; L1/below-L2 MAY defer): flaky tests auto-quarantined via the supervisor + .gates/quarantine.json. The quarantine mechanism is wired (supervisor adopted) and the state file is present with atomic-write perms. Met by adop |
| TS-26 | N/A | mgf-tele-core is pure-Python — src/mgf/tele/core/ contains only .py modules + py.typed; no Zig/Go/Rust/C/Swift compiled artifact is shipped or depended on. No tests/smoke/test_<binary>_ | TS-26 MAY be declared N/A for pure-Python libraries with no compiled artifacts (the rule names mgf-common itself as the analogue). Not applicable. |
| TS-27 | ✅ | .gates/last-run/failures/ bundle directory exists (currently empty because all 49 tests passed — bundles are written per failed/hung/crashed test). The supervisor (mgf.test_supervisor.s | TS-27 MUST: failures explorable from a single per-failure bundle at .gates/last-run/failures/<id>.txt. The harness directory is present and the supervisor (which writes the bundles) is adopted; verifiable post-hoc on a failed run. |
| TS-28 | ⏳ | The run.jsonl records are schema_version '1.0.0' and carry NO perf field (verified: has-perf-field=False across all 49 records); TS-28 requires perf attribution surfaced through TestRec | TS-28 is L2 ('every L2 project; L1 projects MAY defer'). mgf-tele-core is a below-L2 seam library; per-test perf attribution is opt-in and deferred here (schema 1.0.0, no perf field, no perf-summary). Deferred-for-cause rather tha |

### API_DESIGN

| Rule | Status | Evidence | Notes |
|---|---|---|---|
| AP-01 | ✅ | src/mgf/tele/core/__init__.py:42-58 — explicit __all__, 15 names, alphabetically sorted, strings-only (no globals() trick). Every submodule also declares __all__: _provider.py:35-40, _f | ✅ [verify-upheld] Confirmed the public surface is enumerated explicitly at every package and module boundary, alphabetically sorted, string-only, no list(globals()) shenanigan. Refute attempt: AP-01 §2.1 also asks for a test asser |
| AP-02 | ✅ | Substantive docstrings on every public name: TelematicsProvider + its 4 abstract methods document raised errors/ownership (_provider.py:80-122), SessionHandle/TrackerCommand/CommandAck  | ✅ [verify-upheld] All public names carry intent/invariants; the seam docstrings even document the raised-exception contract (open_session→MalformedHandshakeError/UnknownTrackerError; receive_packet→SessionClosedError + the no-rais |
| AP-03 | ✅ | pyproject.toml:7 version = "0.1.5" (MAJOR.MINOR.PATCH). CHANGELOG.md:5-9 invokes Keep-a-Changelog + SemVer + the 0.x clause + rule AP-03, with tight-pin guidance and per-release entries | ✅ [verify-upheld] Valid SemVer string inside the 0.x window with a SemVer-aware Keep-a-Changelog history. No refutation found. |
| AP-04 | N/A | grep for 'deprecat'/'DeprecationWarning' in src/mgf/tele/core/*.py → zero hits; CHANGELOG.md has no [Deprecated]/[Removed] entries (0.1.5/0.1.4 are pin-walk PATCH/MINOR, 'No API change' | AP-04 governs the announce→survive→remove cycle for a DEPRECATED name. No public name is deprecated anywhere in this seam library, so the rule's premise does not bind. N/A (will apply the first time a name is deprecated). |
| AP-05 | ✅ | The 4 abstract methods take only required session/cmd params (_provider.py:85-122). The one growable constructor MockTelematicsProvider.__init__ (mock.py:48-54) places imei/codec_id AFT | ✅ [verify-upheld] No required-positional-growth surface; the constructor that grows uses keyword-only defaults per §5.1. Refute attempt on the frozen dataclasses: TrackerCommand/CommandAck/GeoPoint add fields positionally-by-defau |
| AP-06 | ✅ | Concrete project-owned return types pinned tightly: open_session -> SessionHandle, receive_packet -> ReceivedPacket, send_command -> CommandAck, close_session -> None (_provider.py:88-1 | ✅ [verify-upheld] Return contracts are concrete and pinned narrowly (list, not Iterable), satisfying §4.2/AP-06; no narrowing/widening in the 0.1.x line. No refutation found. |
| AP-07 | ✅ | _errors.py:25-52 — TelematicsError(AppError) base (line 25, imports AppError at line 12) + 6 subclasses all rooted in mgf.common.exceptions.AppError. MockExhaustedError subclasses Telem | ✅ [verify-upheld] Exceptions are a typed hierarchy rooted in the project base AppError, and the public functions document which they raise per §6.1/6.2. Refute attempt: AP-07 message/hint discipline (EH-09 actionable-hint pinning) |
| AP-08 | ✅ | grep -L 'from __future__ import annotations' over src/mgf/tele/core/*.py returned EMPTY (every module has it): __init__.py:18, _provider.py:23, _frames.py:18, _errors.py:10, mock.py:12. | ✅ [verify-upheld] Verified by grep that no source file lacks the future-annotations import, with proper TYPE_CHECKING gating of type-only imports per §7.1/AP-08. No refutation found. |
| AP-09 | ✅ | ls confirms src/mgf/tele/core/py.typed exists (0-byte PEP 561 marker). pyproject.toml:55-58 ships src/mgf via the PEP 420 namespace build (packages = ["src/mgf"]), so hatchling walks th | ✅ [verify-upheld] The package ships type annotations and includes the py.typed marker so downstream mypy --strict can consume it; the wheel-build target walks src/mgf and picks it up. No refutation found. |
| AP-10 | ✅ | `ls PUBLIC_API.md docs/PUBLIC_API.md` → No such file; no generator (`tools/` absent, grep PUBLIC_API in src → none). __all__ exists (src/mgf/tele/core/__init__.py:42-58, 14 names; mock. | AP-10 MUSTs a PUBLIC_API.md enumerating every public name with tier + one-line description, in CI-checked sync with __all__. It is absent. Smallest fix: add PUBLIC_API.md listing the 16 public names (the 14 in __init__ __all__ + M — FIXED 2026-06-09: PUBLIC_API.md lists all public names + tier |
| AP-11 | ✅ | No PUBLIC_API.md exists (see AP-10), so no per-name tier column ('experimental'/'stable'/'deprecated'). No `# tier:` markers in src/mgf/tele/core/*.py. CHANGELOG only references the 0.x | AP-11 MUSTs a declared stability tier per public name. With no PUBLIC_API.md and no tier markers, every public name's tier is undeclared. Smallest fix: add the tier column when creating PUBLIC_API.md (all names start 'experimental — FIXED 2026-06-09: tier declared (experimental, 0.1.x) |
| AP-12 | N/A | CHANGELOG.md (full, 117 lines): [Unreleased]='Nothing yet'; [0.1.5]/[0.1.4] are pin-walks explicitly stating 'No API change' / 'CLI-only release ... no library surface change'; grep 'br | AP-12 MUSTs migration recipes (symptom/before/after/why) for BREAKING changes in the CHANGELOG. No breaking change exists to document, so the rule's premise does not bind. N/A until the first break lands. |
| AP-13 | ✅ | `grep -rn '__version__' src/` → zero hits; src/mgf/tele/core/__init__.py (lines 18-58) has the docstring, __future__ import, re-exports and __all__ but NO __version__ assignment. pyproj | AP-13 MUSTs a __version__ attribute on the top-level package mirroring pyproject.toml::project.version, CI-pinned. __version__ is missing entirely (not merely out of sync). Smallest fix: add `__version__ = "0.1.5"` to __init__.py — FIXED 2026-06-09: added __version__='0.1.6' to __init__.py (was MISSING) + in __all__, mirrors pyproject; version-mirror pin test + CI tag-coherence — released 0.1.6 |
| AP-14 | 🚫 | .woodpecker.yml runs `lint-imports`, but [tool.importlinter] in pyproject.toml defines only ONE contract: a `forbidden` contract stopping the production core (_frames/_provider/_errors) | AP-14 MUSTs an import-linter contract enforcing that consumer test fixtures only touch the public surface (no `_`-prefixed internal modules imported across the boundary). The single existing contract is a layering/core-purity rule — DECLINED 2026-06-09 (CFM-04): the AP-14 closed-box 'consumer fixtures touch only the public surface' contract belongs in a CONSUMER repo; a single-package seam lib has no in-repo external consumer fixtures to gate. The core-purity + PR-01 UI-forbid contracts (2 kept) + the complete PUBLIC_API satisfy the intent. |
| AP-15 | N/A | No shim modules exist: src/mgf/tele/core/ holds only __init__.py, _errors.py, _frames.py, _provider.py, mock.py, py.typed; grep 'DeprecationWarning'/'warnings.warn'/'audit' in src → zer | AP-15 governs backward-compatibility SHIMS (an old name kept working while internals move) — they MUST emit DeprecationWarning + INFO-once-per-process audit log. This 0.1.x seam library ships no shims (it has had no removals to sh |
| AP-16 | ✅ | pyproject.toml pins the cornerstone with the federation window `mgf-common>=0.41,<1.0` (floor kept, ceiling <1.0 per API_DESIGN §4.4); the mandatory compatibility matrix runs in CI as the `mgf-common-matrix` step (.woodpecker.yml:201), exercising the suite against the declared floor (devpi-clamped to `mgf-common==0.44.*`, the oldest series the index serves). | Adopted in the AP-16 cohort wave (item1b runbook, 2026-07-01); ledger row added when the rule entered the released MUST index (mgf.standard 0.1.61 reconciled the count 264→265). |

### SCOPE

| Rule | Status | Evidence | Notes |
|---|---|---|---|
| SP-01 | ✅ | No SCOPE.md anywhere (root *.md = AGENTS/CHANGELOG/CONTRIBUTING/DEPS/FEDERATION/FEEDBACK/LESSON_LEARNED/README/SECURITY/STARTHERE; docs/ = claude/CLAUDE.md + inprogress/MGF_STANDARDS_CO | SP-01 (MUST publish an explicit IN-scope list) is unmet. Smallest fix: add SCOPE.md with a §1 IN-scope list — the TelematicsProvider seam ABC, the codec-agnostic AVL frame types, the typed error hierarchy, and the scripted mock — — FIXED 2026-06-09: SCOPE.md §1 |
| SP-02 | ✅ | No OUT-of-scope list with reasoning exists. grep -i 'out-of-scope' over all repo *.md and docs/ returned no matches (only SECURITY.md matched the broader 'scope' grep). README/CONTRIBUT | SP-02 (MUST publish an explicit OUT-of-scope list with reasoning + alternative) is unmet. Smallest fix: add a §2 OUT table to SCOPE.md, e.g. per-vendor codec parsing (use mgf-tele-teltonika/…), transport/socket I/O (consumer's ing — FIXED 2026-06-09: SCOPE.md §2 |
| SP-03 | ✅ | CONTRIBUTING.md:31-51 'Process' lists PR steps (file feedback, four-gate CI, CHANGELOG entry, seam-surface delta flag, reviewer) but contains NO scope-creep gate requiring a new module/ | SP-03 (every PR adding a module/top-level function MUST justify §1/§3/§2) is unmet — the justification gate and the scope sections it references are both absent. Smallest fix: add the §4 scope-creep question to SCOPE.md and refere — FIXED 2026-06-09: SCOPE.md §3 |
| SP-04 | ✅ | No Adjacent-scope (§3) list exists, so there is no item gated on a documented consumer-demand signal. FEEDBACK.md (the PAPER-NN demand-signal mechanism) and FEDERATION.md exist, but no  | SP-04 (Adjacent items MUST require a documented consumer-demand signal before promotion to IN) is unmet — no Adjacent list and no promotion criterion. Smallest fix: add a §3 Adjacent list to SCOPE.md (e.g. a control-plane send_com — FIXED 2026-06-09: SCOPE.md §4 |
| SP-05 | ✅ | No OUT-of-scope list exists at all (see SP-02), so a fortiori there are no ecosystem-alternative citations per cut. No table maps a deferred capability to the tool that already does it  | SP-05 (the OUT list MUST cite the ecosystem alternative) is unmet, contingent on SP-02. Smallest fix: in the same SCOPE.md §2 OUT table, populate the 'what you should use instead' column for every cut (e.g. per-vendor codecs → mgf — FIXED 2026-06-09: SCOPE.md §5 |
| SP-06 | ✅ | No scope-revisit clause exists. grep for 'MAJOR release\|revisit' over all *.md returned nothing. CONTRIBUTING 'Release flow' (54-60) covers REL-* bump/build/tag/cohort-catch-up but say | SP-06 (scope policy MUST be revisited on every MAJOR release; the MAJOR boundary is the only place a previously-IN item may be removed per AP-04) is unmet. Smallest fix: add a §6 versioning/revisit clause to SCOPE.md stating the p — FIXED 2026-06-09: SCOPE.md §6 |

### WORKFLOWS

| Rule | Status | Evidence | Notes |
|---|---|---|---|
| WF-01 | ✅ | .woodpecker.yml:13-16 `when:` block lists `event: push`, `event: pull_request` (and `manual`). Every push to a long-lived branch and every PR triggers the run; no local-only ship path. | [verify-upheld] Confirmed verbatim: lines 13-16 are exactly `when:` / `- event: push` / `- event: pull_request` / `- event: manual`. The CI run is the canonical gate. MUST met. |
| WF-02 | ✅ | All four gates present and CI-run: lint = ruff check src tests + lint-imports (:25-26); typecheck = mypy (:34); test = pytest matrix on 3.11/3.12/3.13 (:39-58) with coverage on 3.12 (-- | [verify-upheld] The four gates run and fail loudly. One refute-worthy detail: the verdict TEXT claims "2 contracts" at pyproject:148-156 but the file declares ONLY ONE contract block (a single forbidden-import 'Production core doe |
| WF-03 | ✅ | .woodpecker.yml has NO tag-event step and NO publish step; the header comment (:5-6) states 'No publish flow yet — when a release is cut, copy the tag-coherence -> smoke -> publish -> v | A published mgf-* library MUST have a tag-driven publish workflow targeting the Codeberg registry. None exists. Per the carve-out this is ⏳ (NOT N/A — it has CI and is published). — FIXED 2026-06-09: tag-driven Codeberg publish chain added to the existing CI (build→tag-coherence→smoke→publish→verify-codeberg) + scripts/verify_codeberg.py |
| WF-04 | ✅ | No publish step exists, so no `codeberg_package_token` from_secret reference is wired. The token-in-secret-store discipline cannot be satisfied because the publish chain is absent. | WF-04 is the credential-storage rule for the (missing) publish step. Because the publish chain is not built, the rule is unmet — ⏳, contingent on WF-03 being closed. — FIXED 2026-06-09: tag-driven Codeberg publish chain added to the existing CI (build→tag-coherence→smoke→publish→verify-codeberg) + scripts/verify_codeberg.py |
| WF-05 | ✅ | No tag-coherence check (TAG_VERSION vs pyproject::version vs __version__) exists in .woodpecker.yml; there is no publish workflow to host it. | The tag-version-coherence gate is part of the absent publish chain. Unmet — ⏳. — FIXED 2026-06-09: tag-driven Codeberg publish chain added to the existing CI (build→tag-coherence→smoke→publish→verify-codeberg) + scripts/verify_codeberg.py |
| WF-06 | ✅ | No build/upload steps exist in .woodpecker.yml; there is no CI-built-wheel-only enforcement because no wheel is built or uploaded in CI. | WF-06 governs the (missing) publish flow's wheel provenance. Unmet — ⏳. — FIXED 2026-06-09: tag-driven Codeberg publish chain added to the existing CI (build→tag-coherence→smoke→publish→verify-codeberg) + scripts/verify_codeberg.py |
| WF-07 | ✅ | No pre-publish smoke step (ephemeral venv install of the freshly-built wheel + __version__ import assert) exists in .woodpecker.yml. | Pre-publish smoke is part of the absent publish chain. Unmet — ⏳. — FIXED 2026-06-09: tag-driven Codeberg publish chain added to the existing CI (build→tag-coherence→smoke→publish→verify-codeberg) + scripts/verify_codeberg.py |
| WF-08 | ✅ | No post-publish verify step (poll Codeberg REST API …/api/v1/packages/magogi-admin/pypi/<name>/<version> for 200) exists in .woodpecker.yml. | Post-publish verification is part of the absent publish chain. Unmet — ⏳. — FIXED 2026-06-09: tag-driven Codeberg publish chain added to the existing CI (build→tag-coherence→smoke→publish→verify-codeberg) + scripts/verify_codeberg.py |
| WF-09 | ✅ | Every external image is pinned: python:3.12-slim (:21,30,47,62), python:3.11-slim (:40), python:3.13-slim (:53), zricethezav/gitleaks:v8.30.1 (:71, exact tag). No `latest`/rolling-major | [verify-upheld] All external CI deps carry specific pins (rolling-minor python:X-slim is the federation-accepted intent per the :8 comment; gitleaks pinned to exact patch v8.30.1). Lockfile present. MUST met. |
| WF-10 | ✅ | The seven steps (lint, typecheck, test-3.11, test-3.12, test-3.13, vuln-scan, secret-scan) declare NO `depends_on:` anywhere in .woodpecker.yml:18-74, so Woodpecker fans them out in par | [verify-upheld] Confirmed: no `depends_on:` keys present; independent gates run in parallel. No publish chain exists, so the only legitimate sequential dependency (build->smoke->upload) does not yet apply. MUST met. |
| WF-11 | ✅ | uv.lock checked in at repo root (deps reproducible from lock). Each step installs via `pip install -e .[dev]` from the pinned, locked tree; images pinned (WF-09). No host-machine state, | [verify-upheld] A re-run against the same commit produces the same outcome: inputs are the pinned images + checked-in uv.lock + in-repo source/tests. No `${VAR}` interpolation pulling host state into the gate steps. MUST met. (Ste |
| WF-12 | ✅ | Each gate runs in its own fresh container as a discretely named step (.woodpecker.yml:20-73); the :8-9 comment states 'failures are per-step in the UI (WF-12)'. No `\|\| true` and no er | [verify-upheld] Confirmed no `\|\| true` masks and no error suppression; each step surfaces its own exit code/command/logs independently. MUST met. |
| 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 | ✅ | git for-each-ref shows v0.1.0..v0.1.4 are objecttype=tag (annotated, taggername Bassam Alsanie, with messages). But v0.1.5 is objecttype=commit — a LIGHTWEIGHT tag pointing directly at  | REL-01 requires every release to have an ANNOTATED git tag of the form v<version> on the build commit. v0.1.5 (the current/published release) is a lightweight tag, so it carries no author/date/message metadata and is GC-prone — th — FIXED 2026-06-09: release tags re-annotated (v0.1.5) on the same build commits + force-pushed (annotated, GC-safe; no content change). 0 lightweight v-tags remain. |
| REL-02 | ✅ | [verify-upheld] CHANGELOG.md documents a strictly monotonic, distinct version history 0.1.0→0.1.1→0.1.2→0.1.3→0.1.4→0.1.5, each a separate release line with distinct content (test harde | REFUTE attempted and FAILED — UPHELD. REL-02 forbids reusing a version string across different wheel contents. Each release bumps the version; the dist/ cache holds exactly one version's artifacts with no overwrite/reuse evidence. |
| REL-03 | ✅ | find for PUBLIC_API* (root + docs/) returns nothing — no PUBLIC_API.md and no PUBLIC_API.json exist. grep for __version__ in src/ returns 'no __version__' (the __init__ ships no __versi | REL-03 requires PUBLIC_API.md to carry the 'reflects master HEAD, not the published surface' banner and PUBLIC_API.json::__version__ to match the tag. The library has neither file, so the banner obligation is unmet. For a publishe — FIXED 2026-06-09: PUBLIC_API.md master-HEAD banner |
| REL-04 | ⏳ | .woodpecker.yml has lint/typecheck/test-3.11/3.12/3.13/vuln-scan/secret-scan steps but an explicit comment 'No publish flow yet — when a release is cut, copy the tag-coherence -> smoke  | REL-04's standing CI answer is a tag-scoped codeberg_package_token Woodpecker secret on the publish step. No publish step exists, so the token-storage discipline for releasing is not established. No violation (no token in chat/env |
| REL-05 | ✅ | [verify-upheld] CHANGELOG.md + tag history show monotonic distinct versions with NO delete-and-republish note and NO PKG-07 botched-upload recovery record. dist/ holds a single version' | REFUTE attempted and FAILED — UPHELD. REL-05 = published-version immutability by policy (no silent content swap of a resolved version). Searched for any delete+re-push / PKG-07 recovery note / version-content-swap evidence — none  |
| REL-06 | ✅ | .woodpecker.yml comment lines 5-6: 'No publish flow yet — when a release is cut, copy the tag-coherence -> smoke -> publish -> verify-pypi chain from mgf-common.' No tag-event step, no  | REL-06 requires the strictly-ordered release flow, operationalized in CI as the tag-driven publish chain (PKG-04/PKG-05). The publish chain is explicitly absent, so the ordered upload+verify flow is not enforced. Gap (not N/A — it — FIXED 2026-06-09: ordered tag→build→tag-coherence→smoke→publish→verify |
| REL-07 | ✅ | [verify-upheld] FEEDBACK.md §2 contains only the template placeholder ('No papers filed yet' + a PAPER-01 shape stub with Status \| OPEN inside a fenced block). grep finds no real PAPER | REFUTE attempted and FAILED — UPHELD. REL-07 requires a release commit to flip every FEEDBACK entry it ships to SHIPPED with a retrospective. No release shipped any FEEDBACK entry (none are filed beyond the template), so there is  |
| REL-08 | ✅ | .woodpecker.yml has no wheel-smoke step (pip install dist/<wheel> into an ephemeral venv + import). Tests run via 'pip install -e .[dev]' against the SOURCE tree, not the built wheel. T | REL-08 requires pre-release smoke that installs the actually-built wheel into a fresh venv and imports every public top-level name; an editable source-tree test suite does not satisfy it. No such step exists. Gap pending the publi — FIXED 2026-06-09: smoke installs the wheel + imports mgf.tele.core before publish |
| REL-09 | ✅ | [verify-upheld] No FEEDBACK entry has ever been flipped to a terminal status (FEEDBACK.md §2 is the empty template; grep finds no real PAPER-NN; the only 'OPEN' is inside the §2 fenced  | REFUTE attempted and FAILED — UPHELD. REL-09 requires a consumer-facing notification paragraph for every FEEDBACK entry flipped to SHIPPED/DEFERRED/REJECTED. There have been no such flips, so there is nothing to notify. Vacuously  |

### PACKAGE_DISTRIBUTION

| Rule | Status | Evidence | Notes |
|---|---|---|---|
| PKG-01 | ⏳ | pyproject.toml [[tool.uv.index]] codeberg-mgf (simple/) + [tool.uv.sources] map mgf-common and mgf-test-supervisor to Codeberg → mgf-* RESOLVE from Codeberg correctly. Published as 0.1. | Resolution config is conformant, but the public-facing install instruction omits the Codeberg index, so the documented consume path is non-conformant. Gap is in README, not committed resolve config. |
| PKG-02 | ✅ | The only committed registry endpoint is [[tool.uv.index]] url = "https://codeberg.org/api/packages/magogi-admin/pypi/simple/" — the canonical §3 simple-index URL, verbatim, no hand-type | [verify-upheld] Every committed endpoint is the canonical §3 form. (No publish chain yet to exercise the upload/REST endpoints, but nothing non-canonical is committed.) |
| PKG-03 | ✅ | .woodpecker.yml has NO publish step (header comment: "No publish flow yet — when a release is cut, copy the … publish -> verify-pypi chain from mgf-common"). No codeberg_package_token / | The token-auth model (write:package CI secret) is not wired because no publish flow exists. Cannot be N/A — it IS a published mgf-* package (0.1.5); the tag-driven token auth is simply absent. — FIXED 2026-06-09: publish uses codeberg_package_token secret-token |
| PKG-04 | ✅ | No ordered publish ritual (gates→build→twine check→upload→REST verify→tag→push) exists in CI or any committed script. .woodpecker.yml stops at lint/typecheck/test/vuln-scan/secret-scan. | The PKG-04 flow is not implemented. (dist/ staleness is a local-hygiene note only since dist/ is gitignored, not a committed-config violation.) — FIXED 2026-06-09: ordered publish ritual |
| PKG-05 | ✅ | No verify-codeberg step in .woodpecker.yml; the only verification reference is the header-comment TODO naming the old "verify-pypi" step to copy. No REST-200 gate against …/api/v1/packa | Post-publish REST verification against Codeberg is absent (no publish chain exists to gate). — FIXED 2026-06-09: verify-codeberg REST poll |
| PKG-06 | ✅ | pyproject.toml: [[tool.uv.index]] name="codeberg-mgf" url=".../pypi/simple/" explicit = true; [tool.uv.sources] mgf-common = { index = "codeberg-mgf" } and mgf-test-supervisor = { index | [verify-upheld] Exactly the §6 dependency-confusion-safe shape: named index with explicit=true + per-package source mapping for every mgf-* dependency (runtime mgf-common, dev mgf-test-supervisor). Refute attempt: README's bare `p |
| PKG-07 | ✅ | CHANGELOG.md follows Keep-a-Changelog with an [Unreleased] section + SemVer pinning guidance; no evidence of any silent same-version content swap or undocumented delete+re-upload. Versi | Immutability-by-policy is honored: no re-upload/content-swap occurred and the CHANGELOG provides the per-version record the rule requires. Nothing refutes it. |
| PKG-08 | N/A | Retention/pruning is an account-wide (magogi-admin) registry-operator concern measured against the ~200 GiB quota across ALL mgf-* packages; a single leaf library's repo has no surface  | Per the standard, retention is enforced by "a scheduled job reporting org package storage vs quota" at the registry-operator level — not adjudicable inside one consumer/leaf library. |
| PKG-09 | ✅ | .woodpecker.yml runs on push/pull_request/manual only; there is NO tag-driven (event: tag, refs/tags/v*) publish step and no codeberg_package_token secret. Header comment explicitly sta | Tag-driven, build-in-CI, secret-token-authenticated publishing is entirely absent. It is a published mgf-* package, so this is a real gap, not N/A. — FIXED 2026-06-09: tag-driven secret-token publish step |
| PKG-10 | ✅ | pyproject.toml name = "mgf-tele-core" (hyphenated dist) with PEP-420 namespace import mgf.tele.core (dotted), [tool.hatch.build.targets.wheel] packages=["src/mgf"] + namespace-package c | [verify-upheld] Naming defers correctly to NM-01..NM-04: hyphenated distribution name, dotted namespace import, PEP-420 implicit namespace. (pypi.org URL drift for the sibling link is handled under PKG-12.) Upheld. |
| PKG-11 | N/A | This is a pure-domain seam library (TelematicsProvider ABC + frame types + errors + mock) with no agent/CLI/recommendation surface; it does not perform sibling published-version checks. | PKG-11 governs an agent's version-resolution behavior; this library ships no such agent code, so the rule has no subject here. |
| PKG-12 | ✅ | Residual pypi.org surface for an mgf-* package: SECURITY.md line 3 links the mgf-* sibling mgf-common to https://pypi.org/project/mgf-common/ (an mgf-* page URL — PKG-10 says the canoni | There IS residual mgf-* pypi.org distribution surface (the sibling-page link + implied install) and the mandated grep-gate enforcement is missing. Third-party links would be allowed, but mgf-common is an mgf-* sibling whose canoni — RECONCILED ✅ 2026-06-09: no residual pypi.org distribution surface |

### DOCUMENTATION

| Rule | Status | Evidence | Notes |
|---|---|---|---|
| DOC-01 | ✅ | Root docs present: README.md, LICENSE, CHANGELOG.md, CONTRIBUTING.md, SECURITY.md, FEEDBACK.md, AGENTS.md, STARTHERE.md, DEPS.md, FEDERATION.md, LESSON_LEARNED.md + docs/ dir (all confi | The uniform ten-doc baseline is satisfied, but a federation sibling MUST also ship PUBLIC_API.md + PUBLIC_API.json (only-library MUST per DOC-01/§2.0.1). Both are absent. Smallest fix: generate PUBLIC_API.md + PUBLIC_API.json from — FIXED 2026-06-09: PUBLIC_API.md + PUBLIC_API.json present |
| DOC-02 | ✅ | docs/ contains only two buckets: docs/claude/CLAUDE.md and docs/inprogress/MGF_STANDARDS_CONFORMANCE.md (find docs -type d -> docs, docs/claude, docs/inprogress). Missing for a sibling: | A federation sibling's minimum-set (§2.0.3) requires at least docs/standards/README.md (pointer-only), docs/cutover/, and docs/recipes/; reference/ and inprogress/ are 'as needed'. Only claude/ + inprogress/ exist. Smallest fix: a — FIXED 2026-06-09: docs/{standards,cutover,recipes} buckets added |
| DOC-03 | ✅ | Neither existing bucket carries a charter README: docs/claude/ has only CLAUDE.md; docs/inprogress/ has only MGF_STANDARDS_CONFORMANCE.md — no docs/claude/README.md or docs/inprogress/R | DOC-03 requires every long-lived bucket to carry its own README.md stating the charter + a one-line description per file. docs/inprogress/ is a long-lived bucket with no README. (docs/claude/ is arguably self-describing per the CL — FIXED 2026-06-09: bucket README charters added |
| DOC-04 | ✅ | CHANGELOG.md:5-9 Keep-a-Changelog header + SemVer + AP-03 0.x window note; line 11-13 tight-pin example; [Unreleased]=Nothing yet (line 20-22); per-release blocks 0.1.5/0.1.4/0.1.3/0.1. | [verify-upheld] CHANGELOG is in the mandated Keep-a-Changelog/SemVer format with the 0.x note, [Unreleased]='Nothing yet' (no pending uncommitted public-API change), and the maiden entry records the full surface. Cited line number |
| DOC-05 | N/A | No docs/cutover/ directory and no breaking change documented; CHANGELOG.md and the current 0.1.5 release record no removed/renamed/reshaped public name. The TelematicsProvider ABC + fra | DOC-05's premise binds only when a breaking change (MAJOR, or MINOR within 0.x per AP-03) ships. No breaking change exists in this project's history requiring a cutover guide, so the rule does not bind. (Note: the missing docs/cut |
| DOC-06 | ✅ | docs/inprogress/MGF_STANDARDS_CONFORMANCE.md: front-matter Status/Scope/Audience/Cross-references (lines 3-11), §1 'You are here' (line 14) with project-shape framing + 'Applicable stan | [verify-upheld] The sole tracking doc conforms to the §3 living-tracker shape: front-matter, §1 framing, per-item rows each with one status marker + a rationale/evidence column. The DOC rows currently read '⏳ pending audit (v2.19  |
| DOC-07 | ✅ | docs/claude/CLAUDE.md (12KB): header 'mgf-tele-core — Claude Reference' (line 1); mgf-common auto-generated block (lines 3-6, 228-298); standing-instructions topic table (lines 43-53);  | [verify-upheld] The required docs/claude/CLAUDE.md is present in the dense §4 dense-lookup format with the mandated sections (file/topic map, cross-cutting rules, build/release, project-specific lookup). Missing claude_common.md i |
| DOC-08 | ✅ | No PUBLIC_API.json exists (ls 'PUBLIC_API*' -> No such file); no generator present (no tools/ dir, grep for 'public_api' in repo .py files returns nothing outside .venv); .woodpecker.ym | DOC-08 requires PUBLIC_API.md to track __all__ (AP-10) and a PUBLIC_API.json generated from __all__ at every release and pinned in CI (two pins). None of the artifact, generator, or CI pins exist. Smallest fix: add a generator tha — FIXED 2026-06-09: PUBLIC_API.json + tools/generate_public_api_json.py + pin |
| DOC-09 | ✅ | No PUBLIC_API.md (the canonical drift-detected doc) exists; .woodpecker.yml has no name-existence lint; the source modules carry no 'See: docs/...' back-reference (src/mgf/tele/core/__i | DOC-09 requires docs that name code to be drift-detected via either a CI name-existence lint or a code-side back-reference. Neither direction is present for the README's symbol table or any reference doc. Smallest fix: add the PUB — FIXED 2026-06-09: md↔__all__ pin |
| DOC-10 | ✅ | FEEDBACK.md §1 Process states status flips OPEN → SHIPPED/DEFERRED/WONTFIX/MOVED (lines 30-32) with a SHIPPED row carrying commit-SHA+release-version; §2 template carries the four-field | [verify-upheld] DOC-10's core — consumer-facing FEEDBACK flow kept separate from the internal docs/inprogress posture — is met, with the correct lifecycle/severity vocabulary and no conflation. (The file's status vocabulary [OPEN→ |
| DOC-11 | ✅ | docs/inprogress/ holds exactly one tracker (MGF_STANDARDS_CONFORMANCE.md, mtime 2026-06-09 per ls --time-style) — a living conformance ledger with per-rule ⏳ rows still pending (e.g. DO | [verify-upheld] The single inprogress tracker is genuinely active (open ⏳ rows, recently modified), not a graveyard. No archival is owed under DOC-11. Met. |
| DOC-12 | ✅ | Within-repo cross-refs are relative: STARTHERE.md Quick-links table → [README.md](README.md), [CHANGELOG.md](CHANGELOG.md), [DEPS.md](DEPS.md), [FEEDBACK.md](FEEDBACK.md), [FEDERATION.m | [verify-upheld] Within-repo cross-references are relative, external/cross-repo refs are necessarily absolute, headings are hierarchical and grep-able. Conformant with DOC-12. Met. |
| DOC-13 | ✅ | FEEDBACK.md header 'Where to file what' routes mgf-tele-core-specific issues HERE and federation-wide issues to mgf-common/FEEDBACK.md (lines 7-12); FB-01 local-numbering convention sta | [verify-upheld] FEEDBACK.md is correctly repo-scoped with the DOC-13 routing rule and FB-01 discipline embedded, plus the agent-facing reinforcement in CLAUDE.md. Met. |
| DOC-14 | N/A | This project is a federation sibling, not a consumer application: README.md:6-8 'A sibling of mgf-common under the mgf.* namespace, and the foundation of the mgf-tele-* family'; pyproje | DOC-14's MUST-have MGF_ADOPTION.md applies to consumer applications only; the ADP-04 carve-out exempts federation siblings (their adoption story is federation_roadmap + own CHANGELOG). mgf-tele-core is a sibling, so the rule does  |
| DOC-15 | ✅ | docs/inprogress/MGF_STANDARDS_CONFORMANCE.md exists at the canonical CFM-01 path; declares 'Declared conformance level: L2 (per CFM-02)' (line 29); uses ✅/🚫/⏳/N/A per-rule markers in it | [verify-upheld] DOC-15's MUST — the project maintains MGF_STANDARDS_CONFORMANCE.md at docs/inprogress/ declaring its level — is satisfied: file present at canonical path, level L2 declared, per-rule marker vocabulary used. Met. |
| DOC-16 | ✅ | DEPS.md at repo root with both directions: §1 'What mgf-tele-core depends on' (mgf-common runtime row with window/why/tier) and §2 'Who depends on mgf-tele-core' (PlasmaMapper 5 import- | [verify-upheld] Bidirectional dependency manifest present with populated §1 and §2 and the verification methodology recorded. The §1 pin shows '>=0.41,<0.42' while CHANGELOG's ceiling is now <0.47 — a freshness/DEP nit, not a DOC- |
| DOC-17 | ✅ | FEDERATION.md is a pointer stub: 'This project is a member of the Magogi Foundation. The federation contract is not maintained here — there is one canonical copy. Read the contract at:  | [verify-upheld] FEDERATION.md is the required pointer stub linking to the canonical contract, not a duplicate. (The link label says mgf-common/FEDERATION.md but resolves to the mgf-standard URL — the canonical home — a label n |
| DOC-18 | ✅ | Coupled-surface drift between the dependency pin and DEPS.md: pyproject.toml:31 pins 'mgf-common>=0.41,<0.47' but DEPS.md:23 §1 still records the window as 'mgf-common \| >=0.41,<0.42'. | DOC-18 (the ripple rule) requires a change to a coupled surface (here the mgf-common dependency window) to update its dependents — DEPS.md §1 names that exact window — in the same commit. DEPS.md is stale. Smallest fix: update DEP — FIXED 2026-06-09: DEPS.md re-verified |
| DOC-19 | ✅ | LESSON_LEARNED.md at repo root (955 bytes, mtime 2026-06-09): append-only dated format with header stating 'Append-only, dated log ... Newest first ... Federation rule: DOC-19' and a se | [verify-upheld] The DOC-19 root LESSON_LEARNED.md is present in the correct append-only/dated template; a seeded file with no real lessons yet is explicitly conformant (presence is the bar). Met. |

### OPERABILITY

| Rule | Status | Evidence | Notes |
|---|---|---|---|
| OP-01 | N/A | mgf-tele-core is a pure-domain SEAM library (src/mgf/tele/core/: _provider/_frames/_errors/mock/__init__ — ABC + frame types + errors + mock). No CLI entry point (no [project.scripts] i | OP-01's rule form ('CLI: --version rich output; service: /version endpoint') requires a command/endpoint surface. A library with no GUI/CLI/service has neither, so OP-01 is N/A — same reconciliation applied to sibling seam libs (m |
| OP-02 | N/A | No CLI/service. The codebase ships an ABC, frozen frame types, a typed error hierarchy, and a scripted mock — there is no app whose 'own state' (config validity, persistent stores, stat | OP-02 (`<app> doctor` probing the app's own state) presupposes an app with mutable state/config. A stateless pure-domain seam library has nothing for doctor to check; mgf-common's `mgf-common doctor` is the federation reference an |
| OP-03 | ✅ | pyproject.toml has NO [project.urls] table at all — `grep -i 'url\|homepage\|repository\|issues\|documentation' pyproject.toml` returns only the codeberg-mgf index URL (line 48), not Ho | OP-03 MUST: pyproject's Homepage/Documentation/Issues URLs must resolve AND CI must verify (HTTP-HEAD lint or at minimum a no-placeholder grep). Two gaps: (1) the [project.urls] table is entirely absent, so PyPI/registry metadata — FIXED 2026-06-09: CI no-placeholder grep |
| OP-04 | ✅ | README.md lines 22-28 surface table names exactly match src/mgf/tele/core/__init__.py __all__ (15 names: ChecksumError/CommandAck/DecodedAvlRecord/GeoPoint/MalformedHandshakeError/Malfo | [verify-upheld] Refute attempted on three vectors and all failed: (1) surface-table-vs-__all__ — every README table name is a real exported symbol and the only non-__all__ name (MockTelematicsProvider) is correctly path-qualified, |
| OP-05 | N/A | No CLI (`mgf-common explain` analogue), no service, no [project.scripts], no config layer in the package (the only config is dev-time tool config in pyproject.toml; the library defines  | OP-05 (`<app> explain` / admin /config endpoint showing active config + per-field source) requires both a runtime configuration and a command/endpoint surface. This seam library has neither — it is configured by its consumers, who |
| OP-06 | N/A | No CLI/GUI/service. The library emits no rotating log file of its own (it is a domain seam; logging is the consumer's responsibility), and there is no `<app> logs` surface possible with | OP-06 (`<app> logs` CLI / Help→View Logs GUI / aggregator URL) requires an app that writes logs to a known sink and a surface to tail them. A pure-domain library writes no operator-facing log file and has no command surface; consu |
| OP-07 | N/A | No CLI/service entry point; nothing to bundle. A diagnostic tarball aggregates redacted config + log tail + crash reports + doctor output + system info — none of which this stateless se | OP-07 (`<app> bundle` diagnostic tarball) presupposes an app with config/logs/crash-reports/doctor and a command surface to invoke. The library has none of those; the bundle command is consumer-shaped (mgf-common itself marks the  |
| OP-08 | N/A | The library creates no state directories: no crash-report dir, no log rotation, no caches. src/ is pure code (ABC, frozen dataclasses in _frames.py, errors, in-memory scripted mock); th | OP-08 (bounded growth for crash reports / log rotations / caches) applies only where the project writes growing on-disk state. A stateless domain seam writes nothing to disk at runtime; retention discipline is a consumer concern ( |
| OP-09 | N/A | Rule's `applies to` column = service. mgf-tele-core is not a service: no listener, no `environment=production` config, no validate_production() — it is a library imported by consumers. | OP-09 (production safety guards refusing dev-shaped values during config validation before listening) is explicitly service-only (OP-09..OP-12 apply 'where a real deployment + alerting story exists'). This library has no deploymen |
| OP-10 | N/A | Rule's `applies to` column = service. No deployable image/manifest — the artefact is a published Python wheel (mgf-tele-core 0.1.5), not a container in a compose/k8s manifest; there is  | OP-10 (versioned container artefacts + rollback runbook, forbidding image:latest) is service-only and concerns deployed images. A pip-installed library has no such artefact. N/A. |
| OP-11 | N/A | Rule's `applies to` column = service. No alerting: no Prometheus rules, no alertmanager, no paging path — the library runs in-process inside a consumer; it raises no alerts of its own. | OP-11 (alerts reach a human + carry runbook_url) is service-only and presupposes a monitored deployment. N/A. |
| OP-12 | N/A | Rule's `applies to` column = service. No backups: the library persists no data (no DB/object-store/state). There is nothing to back up or restore. | OP-12 (backup+restore drill against the real target) is service-only and presupposes durable production state. A stateless seam library has none. N/A. |

### DEPLOYMENT

| Rule | Status | Evidence | Notes |
|---|---|---|---|
| DEP-01 | N/A | DEPLOYMENT.md:7-24 scope = "stateful web-service consumer applications"; line 20-21 "Out of scope. Federation libraries (no runtime)". DEP-01 "Applies to: service" (line 41). mgf-tele-c | Infrastructure-as-Code binds the consumer web-service that deploys cloud resources, not a library with no runtime/no cloud footprint. The IaC obligation lives in PlasmaMapper's deploy/, not here. |
| DEP-02 | N/A | DEPLOYMENT.md DEP-02 "Applies to: service" (line 42); §8.4 line 793 "platform owns the VM lifecycle -> DEP-02 is N/A." mgf-tele-core owns no VM/container — it is a library imported by c | Configuration-as-Code (Ansible/cloud-init) governs production VM state. A telematics seam library configures no VM; the rule has no premise to bind. |
| DEP-03 | N/A | DEPLOYMENT.md DEP-03 "Applies to: service" (line 43); the rule governs deploy-time artefact immutability + lock-file install for a running service. mgf-tele-core is published via PKG/RE | Artefact-immutability-at-deploy is the consumer application's contract (it pins this library in its uv.lock). The library's own version-immutability is governed by PACKAGE_DISTRIBUTION PKG-07/RELEASING, not DEP-03. No deploy step  |
| DEP-04 | N/A | DEPLOYMENT.md DEP-04 "Applies to: service" (line 44); concerns DB credentials/signing-keys/TLS-private-keys for a production service. mgf-tele-core handles no production secrets (it is  | Production-secret management binds the deployed service. A pure library stores/handles no production secrets; SC-01 secret discipline for the codebase is audited under SECURITY, not DEP-04. |
| DEP-05 | N/A | DEPLOYMENT.md DEP-05 "Applies to: service" (line 45); governs deploy/scripts/deploy.sh environment-explicitness. No deploy/ dir exists (confirmed via ls); no operator deploy/backup/rest | Environment-explicit deploy commands are a property of a deployed service's scripts. The library ships no deploy scripts; nothing to gate on an env arg. |
| DEP-06 | N/A | DEPLOYMENT.md DEP-06 "Applies to: service" (line 46); governs release rollback runbook with drill-measured bound. mgf-tele-core has no release-rollout/rollback surface — it is consumed, | Reversible deploys + numbered rollback runbook bind the consumer service. A library's reversibility is its consumers' pin-rollback in their lockfile, governed there, not by DEP-06 here. |
| DEP-07 | N/A | DEPLOYMENT.md DEP-07 "Applies to: service" (line 47); §3 line 199-209 "deploy/ lives at the repo root of a CONSUMER application". No deploy/ dir present (ls confirmed NO deploy/). DOCUM | The deploy/ directory shape is mandated for consumer applications only. A federation seam library legitimately has no deploy/; the rule's premise does not bind. |
| DEP-08 | N/A | DEPLOYMENT.md DEP-08 "Applies to: service" (line 48); requires deploy/docs/slo.md + burn-rate alerts + paging for a running production service. mgf-tele-core exports no production metri | End-to-end observability + SLO/error-budget bind the deployed service. The library emits structured logs per LOGGING when imported, but has no production sink/SLO obligation; DEP-08 does not bind. |
| DEP-09 | N/A | DEPLOYMENT.md DEP-09 "Applies to: service" (line 49); governs DNS records + auto-renewed TLS for a service's hosts. mgf-tele-core owns no DNS/TLS/hosts (pure library; no network endpoin | DNS + TLS management binds the consumer service's edge. A telematics seam library has no hostnames or certificates; the rule has no premise. |
| DEP-10 | N/A | DEPLOYMENT.md DEP-10 "Applies to: service" (line 50); requires deploy/docs/first-production-cut.md green-field provisioning runbook. No deploy/ dir (ls confirmed); the library has no gr | The first-production-cut runbook documents provisioning a deployed service. A library is not provisioned to production cloud infra; the obligation lives in the consumer (PlasmaMapper). |
| DEP-11 | N/A | DEPLOYMENT.md DEP-11 "Applies to: service" (line 51); requires deployability to >=2 environments (prod + staging/dev) from shared IaC. mgf-tele-core has no IaC/environments (no deploy/t | Multi-environment deployability is a consumer-service property parameterised by tfvars. A library is imported uniformly everywhere — there is no per-environment deploy of the library itself. |

### PRESENTATION_LAYER

| Rule | Status | Evidence | Notes |
|---|---|---|---|
| PR-01 | ✅ | grep -rE over src/ for PySide6\|PyQt6\|textual\|rich\|prompt_toolkit\|click\|typer\|fire\|flask\|fastapi\|django\|starlette\|jinja2\|qasync returns NONE — src/mgf/tele/core is source-cl | PR-01 always applies (even with zero UI consumers — 'protects the future you'). Its MUST has two clauses: (a) no UI-framework import under the SDK root — SATISFIED substantively (src is clean); (b) 'The rule MUST be enforced mecha — FIXED 2026-06-09: import-linter UI-forbid contract (include_external_packages; 2 kept/0 broken) |
| PR-03 | N/A | mgf-tele-core is a pure-domain SEAM library — src/mgf/tele/core/ holds 5 modules (_provider ABC, _frames, _errors, mock, __init__); no GUI/CLI/web/TUI consumer, no <app> repo, no core/v | PR-03 governs the three-layer separation INSIDE a consumer <app> repo with a UI. PR-07 explicitly permits 'A pure-SDK sibling with zero UI consumers MAY mark PR-02..PR-05 as N/A (rule activates at the first UI).' This SDK has zero |
| PR-04 | N/A | No app repo and no UI layers exist to enforce a hierarchy over (no core/view/ui tree). The SDK's own import-linter (pyproject lines 148-161, run via .woodpecker lint-imports) carries on | PR-04 is the app-repo layer-hierarchy enforcement rule, activating with the UI consumer / app. As a pure-SDK with zero UI consumers it falls under the same PR-07 N/A allowance as PR-02..PR-05. (Note: the SDK-level mechanical UI-fr |
| PR-05 | N/A | There are no ui/<framework>/ adapters in this repo (src is the seam library only: provider ABC, frame types, errors, mock). Sibling-UI isolation has no subject — zero UIs, let alone two | PR-05 ('each ui/<framework>/ adapter MUST consume view/ only — never a peer ui') is only meaningful when ≥2 UIs exist in an app repo (the standard says so at §6: 'sibling-UI isolation is only meaningful when ≥2 UIs exist'). With z |
| PR-07 | ✅ | docs/inprogress/MGF_STANDARDS_CONFORMANCE.md contains a PRESENTATION_LAYER section with one row per applicable PR-* id — PR-01, PR-03, PR-04, PR-05, PR-07 (verified via header/row lines | PR-07's hard MUST — 'a sibling at L1+ WITH a UI consumer MUST have a PR section' — does NOT bind here (zero UI consumers). The MUST that binds — 'Conformance trackers MUST classify PR-* rules per the audit-outcomes taxonomy (✅/❌/⚪ |

### AGENTS

| Rule | Status | Evidence | Notes |
|---|---|---|---|
| AG-01 | ✅ | /home/bassam/PycharmProjects/mgf-tele-core/AGENTS.md (37 lines) is a thin pointer ('Run mgf-common agents and do exactly what it prints'); diff against /home/bassam/PycharmProjects/mgf- | [verify-upheld] AGENTS.md ships at repo root, is byte-identical to the federation template, carries no briefing copy, and routes project-specific notes to docs/claude/CLAUDE.md. Fully met. |
| AG-02 | ✅ | AGENTS.md:9 points at the single source 'mgf-common agents'; AGENTS.md:24-34 names the STARTHERE.md mirror fallback (mgf-common/STARTHERE.md confirmed present). docs/claude/CLAUDE.md:12 | [verify-upheld] The canonical briefing is 'mgf-common agents'; the repo points at that single source and keeps project-specific lookups in the CLAUDE.md auto-block. Met. (The tests/unit/cli/test_agents.py named in AGENTS.md is mgf |
| AG-03 | ✅ | git log shows agent-authored commits carrying BOTH trailers: acfe8df / 10524f2 / b4cf83f / c3569609 / 5316023 / badf463 each end with 'Signed-off-by: Bassam Alsanie <bassam@magogi.org>' | [verify-upheld] Recent agent commits carry both signing trailers with the canonical human identity (bassam@magogi.org) and the model Co-Authored-By; the .gitmessage template enforces the shape. Met. (Two historical commits — 4d174 |
| AG-04 | N/A | FEEDBACK.md present (root, §1 Process + §2 Open feedback template + §4 submission); mgf-common feedback CLI available via dep. | AG-04 is a behavioral MUST governing how an agent reacts to friction (file a paper, not a silent local workaround). It is not a static artifact a pure telematics-seam library can satisfy by file state. The repo provides the requir |
| AG-05 | N/A | No repo artifact; AGENTS.md §9 marks AG-05 'Self-enforcement; runtime memory subsystem already prompts the agent to verify.' | Pure agent-runtime behavior (verify memory claims before recommending action). It binds an agent session, not the static state of a telematics-seam library. Nothing in the repo can satisfy or violate it as a file. |
| AG-06 | N/A | .claude/settings.json present; AGENTS.md §9 marks AG-06 'Runtime / harness enforcement (permission prompts) — not a code rule.' | Risky-action confirmation is a runtime/harness obligation on the agent, not a checkable property of a library repo. Premise does not bind static state. |
| AG-07 | N/A | AGENTS.md §9 marks AG-07 'Self-enforcement; runtime reminders surface stale task lists.' | TaskCreate/TaskUpdate usage is a per-session agent behavior; no library artifact binds it. |
| AG-08 | N/A | AGENTS.md §9 marks AG-08 'Self-enforcement; runtime auto-memory rules cover this.' | Memory-scoping discipline is a runtime agent behavior; nothing in a pure-library repo can satisfy or violate it. |
| AG-09 | N/A | AGENTS.md §9 marks AG-09 'Review-only.' pyproject pins mgf-common>=0.41,<0.47 via the codeberg-mgf index (lines 30-31, 46-52). | Verify-sibling-version-against-Codeberg-registry is an agent action during a pin decision, not a static artifact. The repo correctly sources mgf-common from the Codeberg index, but the rule itself binds agent behavior, not file st |
| AG-10 | N/A | AGENTS.md §9 marks AG-10 'Review-only.' | Standards-drift-found-MUST-become-a-PAPER is an agent-behavior rule; not bound by a library's static state. |
| AG-11 | N/A | FEEDBACK.md §1/§4/§5 document cross-project routing (mgf-tele-core-specific HERE; federation-wide → mgf-common/FEEDBACK.md); docs/claude/CLAUDE.md feedback-discipline block restates rou | AG-11 (route feedback to the TARGET project's FEEDBACK.md with enough to triage) is a behavioral routing rule for agents/consumers. The repo provides correctly-shaped channels and routing docs, but the MUST binds the act of filing |
| AG-12 | ✅ | docs/claude/CLAUDE.md (314 lines) present with a populated mgf-common auto-block (BEGIN/END markers lines 3-297) and a 'Project-specific lookup' section (line 302). mgf-common is a hard | [verify-upheld] The project-scoped briefing content lives in docs/claude/CLAUDE.md and mgf-common is installed as a dependency, so 'mgf-common agents --project' surfaces this project's own agent docs. The required content surface  |
| AG-13 | N/A | No repo artifact; governance rule (only mgf-common supervisor changes a library). | AG-13 is a federation-governance behavior constraining who edits a library; it does not bind the static state of mgf-tele-core itself. Premise does not apply to a file audit. |
| AG-14 | N/A | AGENTS.md §9 / AG-14 text: mechanical backstop is 'mgf-common doctor --standards'; otherwise an agent-behavior propagation rule. | Propagate-coupled-surfaces-in-the-same-change binds the agent's editing behavior at change time, not the resting state of a pure-library repo. The doctor --standards backstop is a CLI gate, not a library artifact. Premise does not |
| AG-15 | N/A | AGENTS.md §9 marks AG-15 'Review-only (the charter grants license, not a checkable artifact).' | AG-15 grants agents standing/license; explicitly not a checkable repo artifact. Does not bind a library's static state. The charter resides in mgf-standard, not the consumer repo. |
| AG-16 | ✅ | pyproject.toml [project.optional-dependencies] dev (lines 35-44) lists mgf-test-supervisor, ruff, mypy, import-linter, pytest* — but NO 'mgf-common[standards]'. grep 'standards' over py | AG-16 is checkable and binds every project: it MUST declare mgf-common[standards] where agents/maintainers run the federation CLI, so the standards corpus resolves and commands like 'mgf-common standards/agents/catch-up' do not de — FIXED 2026-06-09: separate [standards] extra |
| 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 | N/A | no performance budgets / perf tests. |
| PF-02 | N/A | no performance budgets / perf tests. |
| PF-03 | N/A | no performance budgets / perf tests. |
| PF-04 | N/A | no performance budgets / perf tests. |
| PF-05 | N/A | no performance budgets / perf tests. |
| PF-07 | N/A | no performance budgets / perf tests. |
| PF-08 | N/A | no performance budgets / perf tests. |
| 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). |


---

## AG-20 — owned-infrastructure discipline (standards v2.26)

✅ **Accounted 2026-06-29.** Review-enforced agent conduct (like AG-04 / AG-05 /
AG-15 — no single checkable artifact). Before declaring an action **blocked /
human-gated / impossible**, an agent consults
[`MGF_INFRA.md`](https://codeberg.org/magogi-admin/mgf-standard/src/branch/main/MGF_INFRA.md)
(the fleet infrastructure / access registry) and attempts the self-owned recovery
path — an auth/access failure on Magogi-owned infra (expired token, 401, stopped
service) is a solvable sub-problem, not a terminal wall. Recorded "blocked" /
"gated" notes carry an unblock-path + as-of date and are re-derived against current
capabilities. Added with the v2.26 corpus bump (AG-20 + the MGF_INFRA registry).
