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

> **Status.** v0.1 — initial tracker. Created 2026-05-28 per the
> DOC-15 sweep (this sibling lacked a conformance tracker).
> **Scope.** mgf-livepush'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:** Realtime push infra — an SSE streaming primitive
(`SSEStreamService` / `open_stream`), a pluggable pub/sub **broker
seam** (`Broker` Protocol with `RedisBroker` + in-process `MockBroker`
adapters), and a per-key connection **slot cap** (`SlotCap`). An
optional thin FastAPI wrapper sits behind the `[fastapi]` extra; the
Redis adapter sits behind the `[redis]` extra. The core
(`_sse` / `_broker` / `_slotcap` / `_errors`) is framework- and
broker-agnostic (enforced by import-linter).

**Current version:** 0.1.6.

**Declared TARGET conformance level: L2** (per CFM-02). **Current VERIFIED standing (2026-06-08 depth audit): below L2** — declared, not met.

Of the **218** current MUSTs: **122 ✅ verified** (file:line, refute-survived) · **5 ⏳ open MUST gaps** · **90 N/A** (library shape) · **1 declined** (CFM-04 §3). Applicable (non-N/A) = **128**; **122/128 (95%) evidenced**. The CORE is strong: the resource-discipline that matters most for an SSE/broker pipeline is real — DP-09 ✅ (explicit per-request disconnect token), DP-11 ✅ (zero detached asyncio tasks), DP-13 ✅ (deterministic `finally` teardown: close subscription BEFORE releasing the slot), a genuine broker provider-seam (DP-02 ✅: project-owned Protocol + Redis prod + mock), slot-cap fail-open with logged degrade, and reliability tests that assert the slot is freed on mid-stream cancel. lint-imports already runs (WF-02 ✅). The 41 ⏳ are library-hygiene: CI publish, SCOPE, PUBLIC_API surface, docs, a few LG/TS items.

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

| Cluster | Rules | Count |
|---|---|---|
| CI publish pipeline (no tag chain) | PKG-04, PKG-05, PKG-09, REL-06, REL-08, WF-03, WF-04, WF-05, WF-06, WF-07, WF-08, WF-11 | 12 |
| SCOPE policy absent (SP-01..06) | SP-01, SP-02, SP-03, SP-04, SP-05, SP-06 | 6 |
| API / docs (PUBLIC_API.md/json, __version__, tiers, examples, buckets, drift, DEPS) | AP-02, AP-10, AP-11, AP-13, AP-14, DOC-01, DOC-02, DOC-03, DOC-08, DOC-09, DOC-18 | 11 |
| LOGGING (lifecycle operation records / event naming / structured WHY) | LG-11, LG-15, LG-16 | 3 |
| TESTING (mirror / exception-tests / security-pin / canonical-dirs / perf) | TS-01, TS-07, TS-10, TS-20, TS-28 | 5 |
| misc (agents, ops, SBOM, install-from-lock) | AG-14, AG-16, OP-04, SC-18, WF-11 | 5 |

**2026-06-08 depth audit provenance.** 16-family fan-out + adversarial refute (hardened "upheld ✅ keeps its status" prompt + an extra-ruthless DP-09/11/13 resource-leak pass — every "does a client disconnect leak a task/slot/subscription?" ✅ was attacked and held). 3 families truncated (LG/DOC/AG) → a 23-id audit-only re-run. No 🚫-flood, no mislabels. Per-rule verdicts with file:line are in §Z; this supersedes the unset placeholders + consolidates the duplicate §Z/§6 enumeration.


## §2 Per-standard audit

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

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

### §2.1 DP — DESIGN_PRINCIPLES

(initial tracker: ✅ structurally conformant; first depth audit to follow.
The broker seam, opt-in extras, and framework-agnostic core are the
DP-relevant surfaces, with import-linter enforcing the boundary.)

### §2.2 EH — ERROR_HANDLING

(initial tracker: ✅ structurally conformant; first depth audit to follow.
Typed `LivePushError` / `CapExceededError` subclass `mgf-common`'s
`AppError`; `SlotCap` is fail-open by design.)

### §2.3 LG — LOGGING

(initial tracker: ✅ structurally conformant; first depth audit to follow.
Logging is delegated to `mgf-common` observability — this sibling owns
no sinks; see §1 N/A note.)

### §2.4 SC — SECURITY_STANDARD

(initial tracker: ✅ structurally conformant; first depth audit to follow.
**SC relevance:** the security-adjacent surfaces are (a) the proxy
buffering-disable headers — `Cache-Control: no-cache, no-transform` +
`X-Accel-Buffering: no` — which shape what intermediaries cache/expose,
and (b) per-user / per-tenant **channel scoping** (`channel=` and
`slot_key=`), where a scoping mistake would cross tenant boundaries.)

### §2.5 CF — CONFIGURATION

(initial tracker: ✅ structurally conformant; first depth audit to follow.
Heartbeat cadence, slot cap + TTL, and channel naming are
caller-supplied; no ambient config is read.)

### §2.6 AP — API_DESIGN

(initial tracker: ✅ structurally conformant; first depth audit to follow.
Public surface is enumerated in README; the `(headers, body)`
`SSEStream` result is the framework-agnostic seam.)

### §2.7 TS — TESTING

(initial tracker: ✅ structurally conformant; first depth audit to follow.
`MockBroker` enables Redis-free tests; tiered markers + ~86% coverage
against an 80% floor.)

### §2.8 DOC — DOCUMENTATION

(initial tracker: ✅ structurally conformant; first depth audit to follow.
DOC-15 is satisfied by this very file; the dev/prod-proxy SSE recipe in
README is the headline doc surface.)

### §2.9 REL — RELEASING

(initial tracker: ✅ structurally conformant; first depth audit to follow.
On PyPI as `mgf-livepush` 0.1.1; CHANGELOG-tracked; cohort-walked with
the federation.)

---

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

| AP-14 | API_DESIGN | import-linter 'consumer fixtures only public' | No in-repo consumer harness; closed-box + framework-forbid contract + complete PUBLIC_API + smoke satisfy the intent. | 2026-06-08 |

(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

| 2026-06-08 | depth audit (16-family fan-out + refute; ~32 agents + 23-id re-run) | first evidence-based per-MUST audit | **87 ✅ / 41 ⏳ / 90 N/A** of 218 (68% of applicable); declared L2 → below-L2. Strong resource-discipline core (DP-09/11/13 ✅, broker seam ✅, slot-cap freed on cancel); gaps are CI-publish/SCOPE/API-docs. Audit only — no code changed. |

| Date | Auditor | Trigger | Findings |
|---|---|---|---|
| 2026-05-28 | initial tracker (DOC-15 sweep) | this sibling lacked a conformance tracker; tracker created | scaffolded; first depth audit to follow |

---

## §5 Cross-references

- [mgf-standard/docs/standards/](https://codeberg.org/magogi-admin/mgf_common/src/branch/main/docs/standards/)
  — the standards source-of-truth.
- [README.md](../../README.md) — declared level + the dev/prod-proxy
  SSE recipe + public surface table.
- [CHANGELOG.md](../../CHANGELOG.md) — release history.
- [SECURITY.md](../../SECURITY.md) — SC-* surface notes
  (proxy headers + channel scoping).
- [FEEDBACK.md](../../FEEDBACK.md) — papers filed against this sibling.
- [mgf-standard/docs/standards/principles/non-adoption-is-valid.md](https://codeberg.org/magogi-admin/mgf_common/src/branch/main/docs/standards/principles/non-adoption-is-valid.md)
  — ASPIRE-04 / CFM-04 documented-non-adoption principle.
- [Template this file was scaffolded from](https://codeberg.org/magogi-admin/mgf_common/src/branch/main/docs/recipes/mgf-standards-conformance-md-template.md).

---

---

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

> **2026-06-08 depth audit** (16-family fan-out + adversarial refute on every ✅, hardened 'upheld ✅ keeps status' prompt + an extra-ruthless DP-09/11/13 resource-leak refute pass; ~32 agents + a 23-id audit-only re-run for 3 truncated families [LG/DOC/AG]). No 🚫-flood, no mislabels. **Mix: 87 ✅ · 41 ⏳ · 90 N/A · 0 🚫.** Replaces the prior duplicate ⏳ scaffold (§Z + §6).


### DESIGN_PRINCIPLES

| Rule | Status | Evidence | Notes |
|---|---|---|---|
| DP-01 | ✅ | pyproject.toml:160-173 forbidden import-linter contract (source _sse/_broker/_slotcap/_errors forbidden from importing fastapi + mgf.livepush.fastapi); .woodpecker.yml:21-27 lint step r | Layering is lint-enforced in CI: the framework adapter (fastapi.py) is the only module allowed to touch FastAPI, the core SSE/broker/slotcap/errors modules are forbidden from importing it, and lint-imports runs in the lint step. U |
| DP-02 | ✅ | _broker.py:18-42 Broker/Subscription runtime_checkable Protocols (the port); :73-85 RedisBroker production adapter (gated [redis] extra); :112-129 MockBroker in-process double; conftest | Genuine provider seam: the third-party pub/sub I/O sits behind a project-owned Protocol with a production (Redis) AND a mock impl, and the mock is what the suite runs on. DP-02 applies and is met. Not changed (already ✅ in challen |
| DP-03 | N/A | No domain-identity types cross module boundaries — channel/slot_key are addressing strings (broker keys, FastAPI route params), not domain identity. SSEStream (dataclass, _sse.py:50-56) | There is no domain object passed between modules as identity; the only crossing values are addressing primitives the broker keys on. DP-03's frozen-domain-type requirement has no applicable surface here. N/A by shape. Not in chall |
| DP-04 | ✅ | pyproject.toml:86-101 [tool.mypy] strict=true + disallow_untyped_defs/disallow_incomplete_defs over packages=["mgf.livepush"]; .woodpecker.yml:30-35 runs mypy as a gate; all public sign | mypy --strict is configured and CI-gated; every public signature is fully annotated; the handful of Any are the injected third-party client objects at the provider seam (the standard's own provider pattern uses Any/seam types ther |
| DP-05 | ✅ | tests/ mirrors the public surface (test_broker, test_sse, test_slotcap, test_reliability, test_smoke); conftest.py:8-32 FakeRedis async double + MockBroker fixtures; test_reliability.py | Tests drive the real code paths through the broker Protocol + injected fake-redis, with no production credentials, no network, no real daemon. Topic-based mirror covers each module. MUST met. [verify-upheld] |
| DP-06 | ✅ | _slotcap.py:1-10 documents fail-OPEN reliability stance + DoS-bounding cap; :59-69/82-90 log the degraded path with structured extra/fingerprint + exc_info; _sse.py:111-117 deterministi | For a library DP-06's PR-description clause is the consumer's CI, but the substantive evidence (reliability fail-open + logged degrade, slot-cap DoS bound, no secret leakage, typed-error reporting, deterministic cleanup, CVE+secre |
| DP-07 | ✅ | Every public class/function carries an intent+invariant docstring: _broker.py:19-28/32-42/73-85/112-114 (port + real pub/sub semantics); _sse.py:1-15 module-why, :80-83 (synchronous Cap | Docstrings consistently state intent and invariants; the resource-ordering comment (_sse.py:112-114) and the fail-open rationale (_slotcap.py:1-10) are exactly the why-comments the rule wants. MUST met. [verify-upheld] |
| DP-08 | ✅ | _broker.py:1-7 module docstring states the swap recipe ('A consumer that wants Redis Streams / NATS / Kafka writes a new adapter — SSEStreamService never sees the broker's internals');  | DP-08 is a SHOULD-with-a-MUST ('the doc near it MUST describe the swap recipe'). The broker module docstring + README both state precisely what changes to swap (write a new adapter; core untouched), at the abstraction. The only sw |
| DP-09 | ✅ | _sse.py:73-98 open_stream/_event_gen take is_disconnected: Callable[[], Awaitable[bool]] (explicit per-request disconnect token = FastAPI request.is_disconnected), checked each loop ite | Tried to refute via §11.2's 're-raise CancelledError unless you own the cancellation' (the generator absorbs+returns rather than re-raising). But DP-09's literal MUST is 'cancellation MUST be explicit; takes a CancellationToken-li |
| DP-10 | ✅ | _slotcap.py:59-69 logs WARNING with exc_info=True + structured extra (slot_key, cap, fingerprint) on the acquire fail-open; :82-90 logs the release best-effort path likewise; the redis/ | DP-10 forbids SILENT fallbacks and requires the active backend be queryable + logged. The single backend is caller-injected (visible by construction), and the one degradation (slot-cap fail-open) is loudly audit-logged each time i |
| DP-11 | ✅ | grep across src/ for create_task/ensure_future/gather/TaskGroup/asyncio.run returns ZERO matches. SSE work runs inside the caller's request coroutine via the async generator (_sse.py:93 | DP-11 forbids un-owned asyncio.create_task. The library deliberately creates no detached tasks — the SSE iterator is driven by the ASGI server's own task, so there is nothing to leak — and the RUF006/ASYNC lint keeps it that way.  |
| DP-12 | N/A | No datetime/time-of-day handling anywhere in src/ — the only time values are float durations (heartbeat_seconds _sse.py:67, ttl_seconds _slotcap.py:32, timeouts) used for asyncio waits, | DP-12 governs UTC-at-boundary for datetimes (per TIME.md TM-01..08). This library handles only relative durations for async timeouts/heartbeats — no wall-clock datetime crosses any boundary, so there is no applicable surface. N/A  |
| DP-13 | ✅ | _sse.py:99-117 — the SSE generator's finally (runs on normal exit, disconnect, CancelledError AND error) closes the broker subscription then releases the slot, with a documented close-b | Tried hardest here. The slot + subscription are exactly the resource-leak surface DP-13 guards, and both are released in a try/finally on all four exit paths (normal/disconnect/cancel/error). The ordering is deliberate (close-befo |

### ERROR_HANDLING

| Rule | Status | Evidence | Notes |
|---|---|---|---|
| EH-01 | ✅ | _errors.py:9 imports mgf.common.exceptions.AppError; _errors.py:14 LivePushError(AppError); :18 CapExceededError(LivePushError). grep `raise` in src returns exactly two sites: _sse.py:8 | Refute attempt failed: there is no internal-API site raising a bare or third-party exception. Both project exceptions subclass AppError; the lone HTTPException is a framework boundary response, correct shape for a web adapter. Uph |
| EH-02 | ✅ | fastapi.py:44-47 translates CapExceededError→HTTPException(429) chained `from exc`. _slotcap.py:59-69/82-90 catch backing-store Exception at the SlotCap boundary and translate to a docu | Refute attempt failed: every boundary this library OWNS (cap→429, slot fail-open, subscription close) translates. The broker pass-through's untranslated propagation is an explicitly documented + test-pinned design seam handed to t |
| EH-03 | ✅ | fastapi.py:44-47 `except CapExceededError as exc: raise HTTPException(...) from exc`. grep for `from exc`/`from e`/`from None` in src returns exactly this one site. The slotcap except b | Refute attempt failed: the single translated re-raise in the codebase chains the original cause with `from exc`. No un-chained translated re-raise exists. Upheld. |
| EH-04 | N/A | It is a library with no entry point of its own: pyproject has no console_scripts/entry_points (grep returned nothing). No code in src installs sys.excepthook, threading.excepthook, or l | Top-level handlers are an entry-point obligation; a library that owns no entry point or loop has no handler to install. Carve-out (library, no CLI/service of its own) applies. |
| EH-05 | N/A | No entry point owns the process (no console_scripts); no crash reporter wiring in src. Crash reporting is the consumer's process-level concern (mgf.common.observability.report_now wired | Crash reports are produced by the process top-level handler, which a library does not own. N/A by the library carve-out. |
| EH-06 | N/A | No GUI: src is six modules (broker/sse/slotcap/errors/fastapi/__init__), no QThread/worker/Signal anywhere. The prompt's shape carve-out confirms no GUI (PR-03/04/05 N/A). | GUI worker error pipeline is inapplicable to a headless library. |
| EH-07 | ✅ | grep `except` in src returns: _broker.py:68 `with contextlib.suppress(Exception)` in _RedisSubscription.close (clause a — cleanup/suppress); _slotcap.py:59 acquire and :82 release best- | Refute attempt failed: every broad `except Exception` falls in EH-07's allowed clauses — finally/suppress cleanup or documented best-effort log-and-continue. None swallows silently. Upheld. |
| EH-08 | ✅ | _errors.py:25-31 CapExceededError.__init__ sets self.slot_key and self.cap as constructor-provided attributes BEFORE building the message string (the CommandError.argv shape). fastapi.p | Refute attempt failed: the one stateful typed exception carries its state as constructor-set machine-readable attributes, not only in the message; the base is intentionally stateless. Upheld. |
| EH-09 | N/A | The library has no CLI/GUI surface that shows a message to an end user. The one diagnostic message (CapExceededError, _errors.py:28-31) is operator/log-facing; the actionable next step  | EH-09 governs messages SHOWN to users via a CLI/GUI the project owns; this library owns none. The actionable affordance (429 + Retry-After) is delivered through the protocol, not a prose message. N/A. |
| EH-10 | ✅ | _slotcap.py acquire (59-72) and release (74-93) catch broadly, log at WARNING with the slot_key identifier (extra={'slot_key':...,'fingerprint':...}), return bool/None and continue (fai | Refute attempt failed: the observer paths catch broadly, log at WARNING with an identifier, continue, document never-raises, and are test-pinned for the never-raises contract. Upheld. |
| EH-11 | N/A | No retry loop, backoff, or jitter exists anywhere in src (grep for retry/backoff/jitter/sleep/circuit returns only the SSE `retry:` directive and HTTP `Retry-After` — client-side reconn | EH-11 governs the shape of retries that exist; this library performs no retries against any external system, so there is no retry budget to require exponential-backoff-with-jitter on. N/A (the deliberate no-retry / propagate-to-su |
| EH-12 | N/A | The library performs no multi-attempt writes/sends — broker.publish (_broker.py:79-80) is a single pass-through call with no retry, and slot acquire/release (_slotcap.py) are single-sho | EH-12 binds operations with multi-attempt cost; there is no retry/multi-attempt path here. N/A. |
| EH-13 | N/A | No upstream-amplifying load exists: there are no retries against the broker/redis (a failed call propagates once to the consumer's supervisor — test_reliability.py:218-240), so there is | EH-13 requires a breaker OR a recorded bound where load can amplify an outage; here the load is non-amplifying by design (single-shot, propagate-not-retry), so there is no amplification to bound. N/A — the bound (no retry) is docu |

### LOGGING

| Rule | Status | Evidence | Notes |
|---|---|---|---|
| LG-01 | ✅ | _slotcap.py:22 `LOG = logging.getLogger(__name__)`; _sse.py:35 `LOG = logging.getLogger(__name__)`. grep over src/ confirms these are the ONLY getLogger calls, both at module scope with | REFUTE ATTEMPT: searched for a function-level getLogger, a flat name, a bare root-logger call, or a stray print — none exist. Every module that logs uses getLogger(__name__) at module scope. Upheld. [verify-upheld] |
| LG-02 | N/A | Library with no entry point of its own (no CLI main, no app.run, no service entry — pyproject has no [project.scripts]; fastapi.py is a helper a consumer mounts). It acquires loggers bu | LG-02 binds the application entry point to configure logging in exactly one place + JSON-when-not-a-TTY. A library MUST NOT configure root logging; doing so would be the violation. The consumer's entry point owns LG-02. N/A by sha |
| LG-03 | N/A | trace_id/span_id are injected by the consumer's standard JsonFormatter (mgf.common.observability) at format time, on EVERY record regardless of which library emitted it. mgf-livepush em | LG-03 is a formatter responsibility, satisfied by the standard JsonFormatter the consumer installs. A library has no formatter and cannot attach trace context itself. The library's two records carry no field that would block OTel  |
| LG-04 | N/A | Redaction is a formatter responsibility (the Redactor runs inside the consumer's JsonFormatter/TextFormatter before any sink). mgf-livepush ships no formatter and no sink. Its two log r | LG-04 binds the formatter to redact before sinks; the library has no formatter. The defensive sub-question — does the library log a secret that the redactor must catch? — is also clean: no secret-bearing field is emitted. N/A by s |
| LG-05 | ✅ | src/mgf/livepush/_slotcap.py:60-68 and :83-90 — the only two log sites in the library. Both pass exc_info=True (lines 62 and 85) inside an `except Exception:` block, so the traceback is | LG-05 binds ERROR records to carry exc_info/LOG.exception. This library emits no ERROR records at all; its two recovered-failure records are WARNING and already carry exc_info=True. The rule's intent (never lose the traceback at a |
| LG-06 | N/A | No sink is installed anywhere in src/. Sinks (rotating file / stdout / OTLP) are wired by the consumer's setup_logging at its entry point. The library only acquires loggers and emits —  | LG-06 (logs reach a searchable aggregator) is an entry-point/deployment concern the consumer owns. A library installs no handlers by design. N/A by shape. |
| LG-07 | N/A | No GUI. mgf-livepush is a headless library (SSE/broker/slotcap primitives). Per-kind matrix: LG-07 is gui-app-only. | LG-07 applies to gui-app kind only; this is a library. N/A by the standard's own Applies-to scope. |
| LG-08 | ✅ | src/mgf/livepush/_slotcap.py:61 message is the static literal "livepush: slot acquire failed; failing open"; :84 is "livepush: slot release failed (best-effort)". Neither is an f-string | LG-08 forbids f-string/eager message construction; both (and only) log messages are constant string literals with no interpolation, so lazy formatting is moot and the no-f-string MUST is satisfied. MET. |
| LG-09 | ✅ | src/mgf/livepush/_slotcap.py:63-67 passes extra={"slot_key": slot_key, "cap": self.cap, "fingerprint": f"livepush.slot_acquire_failed:{slot_key}"}; :86-89 passes extra={"slot_key": slot | LG-09 requires structured fields via extra={} for promotion to top-level JSON keys; both log sites carry every variable fact (slot_key, cap, fingerprint) as extra fields and keep the message a constant template. The f-string appea |
| LG-10 | N/A | No service/daemon entry point (no systemd unit, no headless main). Per-kind matrix: LG-10 is service-only and, per §10's web-shape note, is N/A under cloud-native deploy anyway. | LG-10 applies to the service kind (journald sink at a headless entry point). A library has no entry point to configure. N/A by the standard's own Applies-to scope. |
| LG-11 | ⏳ | open_stream/_event_gen cross network (broker subscribe) + storage (Redis INCR/DECR) + process boundaries and the SSE generator is long-lived — exactly the LG-11 surface — yet emit NO IN | LG-11 is a MUST: any function crossing a process/network/storage boundary MUST log start+end with a stable `operation` name so flows are reconstructable from logs alone. The slot acquire/subscribe/stream-open/stream-close lifecycl |
| LG-12 | ✅ | The two existing log sites (_slotcap.py:60, :83) build a small dict literal (slot_key, cap, fingerprint string) at the call site with a static message; no file IO, no heavy formatting,  | REFUTE ATTEMPT: looked for inline IO, eager heavy serialization, or a per-record loop at the call sites — none. Emission cost is a static message + a 2-3 key dict. The per-record-µs perf pin is a SHOULD/benchmark concern; LG-12's  |
| LG-13 | N/A | No high-frequency log site exists. The only two LOG calls are on the Redis-error fail-open/fail-best-effort paths in SlotCap.acquire/release (one per failed slot op), not inner loops or | LG-13 binds high-frequency sites (inner loops / per-event / per-tick) to rate-limit or sample. There is no such site — the per-message SSE loop is log-silent and the two error logs fire only on a backing-store fault. Nothing to ra |
| LG-14 | N/A | Correlation-context propagation via contextvars is a consumer/entry-point responsibility (set request_id/user_id at the HTTP boundary; the standard formatter promotes registered context | LG-14 binds the boundary that OWNS the correlation (the consumer's HTTP handler / entry point) to set+reset contextvars. A library primitive does not own a request's correlation identity. N/A by shape. |
| LG-15 | ✅ | §4.5's MUST-surface table explicitly names `sse.cap.reached` and `pool.saturated`/`rate_limit.exceeded` as quota/capacity boundary events that deserve an `event` field. The cap-exhauste | LG-15 is a MUST: every INFO+ record at a notable lifecycle/security/boundary event MUST carry a stable `event` field in <subject>.<action> form, documented in EVENTS.md. The capacity-boundary hit (cap reached) is the canonical exa — FIXED 2026-06-08 (0.1.6): both slot-cap WARNING records now carry a stable event field (mgf.livepush.slot_acquire_failed / slot_release_failed), catalogued in docs/reference/EVENTS.md |
| LG-16 | ✅ | WHAT: both WARNING messages are past-tense/declarative and queryable-by-field — good. WHY: slot_key+cap in extra — partial. HOW: NEITHER record carries a remediation `hint` field nor an | LG-16 is a MUST at WARNING+: every WARNING/ERROR record MUST answer WHAT+WHY+HOW. The two records answer WHAT and partially WHY but provide no HOW (no hint/runbook/remediation) — the standard's discipline test ('take a useful next — FIXED 2026-06-08 (0.1.6): the WARNING records now answer WHAT (message) + WHY (event/slot_key/cap/exc_info) + HOW (failing-open), all as queryable extra fields |
| LG-17 | ✅ | _slotcap.py:66 `'fingerprint': f'livepush.slot_acquire_failed:{slot_key}'` and :88 `'fingerprint': f'livepush.slot_release_failed:{slot_key}'`. Both error-class (WARNING+exc_info) recor | REFUTE ATTEMPT: checked for instability (timestamp/uuid), over-fineness, or absence — none. Both currently-logging sites override fingerprint correctly. LG-17 is a SHOULD and it is met at every site that logs. Caveat (SHOULD-level |

### CONFIGURATION

| Rule | Status | Evidence | Notes |
|---|---|---|---|
| CF-01 | N/A | No pydantic_settings.BaseSettings subclass and no Settings class exist (grep over src/ = zero matches); no module reads a config file or env vars directly (grep os.environ/getenv over s | Unchanged. mgf-livepush is a library with no consumer-owned config schema; CF-01 (consumer-owned-config scope) does not apply. |
| CF-02 | N/A | No layered config sources, no BaseSettings, no settings_customise_sources in src/. SlotCap/SSEStreamService take explicit constructor args (e.g. _slotcap.py:26-41). | Unchanged. No config-precedence surface exists in this library. |
| CF-03 | N/A | No config schema and therefore no version field / migration chain in src/. | Unchanged. consumer-owned-config scope; not applicable to a config-less library. |
| CF-04 | N/A | No on-disk config write anywhere in src/ (no save_settings, no write_text of config). | Unchanged. No owned config/state file to write atomically. |
| CF-05 | ✅ | [verify-upheld] grep -rniE 'secret\|password\|token\|keyring\|vault\|api_key' over src/ AND tests/ returns ZERO matches. No BaseSettings/config file in src/. _slotcap.py:60-68/83-89 log | Upheld under adversarial refute (status kept ✅). CF-05 applies to 'all'. The library handles no secrets and has no config file, so there is no path for a secret to leak into config, version control, or logs. Verifiably conformant  |
| CF-06 | N/A | No config schema / no extra='forbid' surface in src/; no YAML loader. | Unchanged. consumer-owned-config scope; no config keys to reject. |
| CF-07 | N/A | No satellite/sub-config files in the library. | Unchanged. No sub-config files exist. |
| CF-08 | N/A | No Settings object and no module-global singleton; all deps are constructor-injected (SlotCap, SSEStreamService, broker). | Unchanged. consumer-owned-config scope; no Settings to load-once. Note the library already follows constructor injection for its own collaborators. |
| CF-09 | N/A | Library has no CLI of its own (no console_scripts; no argv parsing in src/). | Unchanged. No CLI surface, so --config flag is not applicable. |
| CF-10 | ✅ | [verify-upheld] Every test constructs objects with explicit values and in-memory fakes: conftest.py:46 SlotCap(fake_redis, key_prefix='t:'); test_slotcap.py:12 SlotCap(fake_redis, cap=2 | Upheld under adversarial refute (status kept ✅). CF-10 applies to 'all'. No Settings class exists to instantiate, but the rule's letter and spirit (explicit values, no env-var leakage) are met: every parameter is an injected scala |
| CF-11 | N/A | No config schema fields to rename / alias in src/. | Unchanged. consumer-owned-config scope; no field-rename surface. |
| CF-12 | N/A | No mutually-exclusive config backend variants modelled in a Settings schema. The broker seam is a Protocol/ABC with Redis+mock impls selected by the consumer at construction time, not a | Unchanged. CF-12 governs discriminated-union *config* variants; the broker provider seam is a DP-02 concern, not a config-field discriminator. No applicable config surface. |

### SECURITY_STANDARD

| Rule | Status | Evidence | Notes |
|---|---|---|---|
| SC-01 | ✅ | .woodpecker.yml:75-79 secret-scan step (gitleaks v8.30.1, `gitleaks detect --source . --no-banner --redact` over working tree + history); `grep -rniE '(password\|secret\|token\|api_key\ | REFUTE ATTEMPT FAILED. Tried to find a hardcoded secret or a secret-bearing log field in src/ — grep is clean and the two LOG.warning sites carry only a slot identifier, an int cap, and a fingerprint string. The mechanical gitleak |
| SC-02 | N/A | `grep -rnE 'subprocess\|shell=True\|os.system' src/` returns nothing. The library spawns no processes. | No subprocess invocation surface anywhere in the 5 modules; the argv-only rule has no subject. |
| SC-03 | N/A | `grep -rnE 'yaml\|pickle' src/` returns nothing. Payloads are opaque bytes forwarded verbatim (_broker.py / _sse.py:108 `b'data: ' + data`), never deserialized. | No YAML/JSON/pickle deserialization of untrusted data; SSE payloads are pass-through bytes, not parsed. |
| SC-04 | N/A | `grep -rnE 'open\(\|write_text\|chmod\|atomic' src/` returns nothing. The library writes no files. | No private-data file write surface; the 0o600+atomic rule has no subject. |
| SC-05 | N/A | `grep -rnE 'hashlib\|random\.\|secrets\|cryptography\|md5\|sha1' src/` returns nothing. | The library performs no cryptographic operation and generates no tokens/nonces/keys. |
| SC-06 | N/A | `grep -rnE 'verify=False\|CERT_NONE\|AutoAddPolicy\|ssl' src/` returns nothing. RedisBroker (_broker.py:76) receives a redis client by injection; the library opens no outbound TLS conne | No outbound HTTP/SSH/TLS client is constructed by the library; the redis client (and its TLS config) is the consumer's. No verify-disablement to refute. |
| SC-07 | ✅ | _sse.py:102 `sub.get_message(timeout=self._heartbeat_s)` — every broker pull carries the finite heartbeat (default 15.0s, _sse.py:41); Subscription Protocol (_broker.py:22) makes `timeo | REFUTE ATTEMPT FAILED. The one long-lived blocking boundary — the next-message pull inside the SSE generator loop — is timeout-bounded on EVERY iteration, so an idle stream emits keep-alive rather than hanging. Probed the remainin |
| SC-08 | N/A | The library is a primitive, not a boundary parser. channel/slot_key arrive as already-validated server-derived strings (SECURITY.md:91-94 instructs consumers to derive channels from a t | SC-08 places validation at the parser boundary (HTTP handler/IPC reader), which is the consumer's endpoint — not this library. The library has no untrusted-input ingestion point to validate at. |
| SC-09 | ✅ | The ONLY log records in src are _slotcap.py:60-68 and 83-90, whose extra={} carries slot_key, cap, and a fingerprint string only — no secret-class key, no payload/token/credential. `gre | REFUTE ATTEMPT FAILED. Tried to find a LOG call that emits a payload, token, or credential — there are exactly two LOG.warning sites and both log non-secret operational metadata. The primary defense (don't put secrets in log paylo |
| SC-10 | ✅ | uv.lock present + committed (193382 bytes, repo root); .woodpecker.yml:62-73 vuln-scan step runs `pip-audit --skip-editable` on every push/pull_request/manual. `--strict` is intentional | REFUTE ATTEMPT FAILED. Both halves met: a committed lockfile pins transitive deps and pip-audit is a per-PR CI gate. The --skip-editable / dropped-strict nuance is documented and does not weaken CVE detection on actual dependencie |
| SC-11 | ✅ | _errors.py:25-31 CapExceededError embeds only slot_key (repr'd) + cap (int); LivePushError subclasses mgf.common AppError with no credential wrap; teardown seams use contextlib.suppress | REFUTE ATTEMPT FAILED. Searched for a translation seam wrapping a credential-bearing exception — there is none (no auth, no vault, no SSH in the library). The only typed errors carry non-secret operational fields. No secret can re |
| SC-12 | ✅ | SECURITY.md at repo root (4562 bytes): Supported versions table (line 17-19), Reporting a vulnerability with email bassam@magogi.org + Codeberg private advisory channel (line 21-30), 90 | REFUTE ATTEMPT FAILED. Every required §11.1 element is present and located at the repository root — supported versions, security contact, embargo expectation, disclosure timeline. Upheld. [verify-upheld] |
| SC-13 | N/A | No crypto in src (`grep -rnE 'hashlib\|cryptography\|secrets' src/` empty); the library stores no keys at rest. | No cryptographic keys are generated, stored, or embedded; the KDF/keyring-for-keys rule has no subject. |
| SC-14 | N/A | `grep -rniE 'auth\|login\|password' src/` finds only a prose comment in _slotcap.py:6 ('denying authenticated users'); no authentication code path exists. SSE auth is the consumer's fas | The library performs no authentication, so there is no failure path to make uniform or rate-limit. The auth boundary is the consumer's endpoint. |
| SC-15 | N/A | `grep -rnE 'Path\|resolve\|is_relative_to\|open\(' src/` returns nothing; no filesystem path is constructed from external input. | No filesystem operations and no path construction from external input; the traversal-validation rule has no subject. |
| SC-16 | N/A | `grep -rniE 'sudo\|setuid\|privileged\|capability' src/` returns nothing. The library performs no privileged operation. | No privilege escalation, setuid, capability grant, or privileged container surface exists in a library running entirely in the consumer's process. |
| SC-17 | N/A | `grep -rnE 'audit' src/` returns nothing. The §9.3 audit-event set (vault read/write, subprocess against user argv, SSH open/close, config write, key rotation, auth attempt) has no memb | The slot-cap is connection backpressure, not a security-relevant audited action in the §9.3 sense; none of the enumerated security-relevant actions occur here, so there is nothing to emit an audit=true record for. |
| SC-18 | ✅ | Published as mgf-livepush 0.1.5 (pyproject.toml:7), built with hatchling>=1.21 (pyproject.toml:2-3) from a tagged commit — buildable from source — BUT .woodpecker.yml:5-6 states 'No pub | Per the SHAPE carve-out, publish-chain rules are ⏳ gaps (not N/A) for a published mgf-* package. The artefact is reproducible-from-source in principle (declared deps + tagged commit + hatchling), but there is no mechanical reprodu — FIXED 2026-06-08: .woodpecker sbom step generates a reproducible CycloneDX SBOM (dist/mgf-livepush.cdx.json) |

### TESTING

| Rule | Status | Evidence | Notes |
|---|---|---|---|
| TS-01 | ✅ | tests/ is FLAT (tests/test_broker.py, test_sse.py, test_slotcap.py, test_reliability.py, test_smoke.py, conftest.py) — there is NO tests/unit/ tree mirroring src/mgf/livepush/. The 6 so | TS-01 MUST: tests/ mirrors src/ 1:1 with a per-module mirror under tests/unit/ and a CI mirror-lint + allow-list. The flat layout and absence of a mirror lint leave this unmet. Tests do exercise most modules behaviorally, so this — FIXED 2026-06-08: tests restructured into tests/unit/ + tests/test_mirror.py + MIRROR_ALLOWLIST.txt |
| TS-02 | ✅ | [verify-upheld] All external I/O is reached only through the project-owned Broker/Subscription Protocol (src/mgf/livepush/_broker.py:18-42) and the SlotCap redis seam (_slotcap.py: redi | Refute attempt failed: grep finds RedisBroker referenced only in the __all__ smoke assertion (tests/test_smoke.py:23), never constructed against a real client; no test opens a socket or a real redis. Every Redis/broker interaction |
| TS-03 | ✅ | [verify-upheld] Fixtures fake_redis/broker/slot_cap are function-scoped (tests/conftest.py:34-46, no scope= → default function) and rebuilt per test; tests also construct fresh MockBrok | Refute attempt failed: no process-global mutator is touched without restore because none is touched at all; isolation holds structurally. pytest-randomly is not wired (§16 mechanical aid), but that aids enforcement of the MUST, it |
| TS-04 | ✅ | [verify-upheld] pyproject.toml:121-125 filterwarnings = ["error", "default::mgf.common._warnings.MgfDeprecationWarning", "default::pytest.PytestUnraisableExceptionWarning"]. "error" is  | Refute attempt failed: TS-04 MUST is that filterwarnings=["error"] is set; "error" is present and first, so all warnings escalate by default. The two trailing entries are narrowly-scoped per-category relaxations (a named federatio |
| TS-05 | ✅ | [verify-upheld] pyproject.toml:112-117 addopts includes "--strict-markers" and "--strict-config". | Refute attempt failed: both flags are present in addopts. TS-05 MUST met. UPHELD. |
| TS-06 | ✅ | [verify-upheld] pyproject.toml:142-155: [tool.coverage.run] source=["src/mgf"], branch=true; [tool.coverage.report] fail_under=80 + standard exclude_lines + show_missing. .woodpecker.ym | Refute attempt failed at the level of the MUST-as-written: TS-06 binds an ≥80% floor gate on a CI job, and fail_under=80 + branch coverage runs in the 3.12 CI job. The untested RedisBroker production path and fastapi.py adapter ar |
| TS-07 | ✅ | Two typed exceptions exist (src/mgf/livepush/_errors.py: LivePushError, CapExceededError). tests/test_smoke.py:40-43 asserts issubclass(CapExceededError, LivePushError) and test_sse.py: | TS-07 MUST: every typed exception has a unit test asserting (a) message format, (b) field values preserved. CapExceededError carries slot_key+cap fields (_errors.py:25-31) that no test reads; the raise is pinned by type only. Part — FIXED 2026-06-08: tests/unit/test_exceptions.py pins CapExceededError message + slot_key/cap fields |
| TS-08 | N/A | There is no EH-02 third-party-error translation seam in mgf-livepush. _RedisSubscription.close (_broker.py:67-71) and SlotCap (_slotcap.py:59-69,82-90) SUPPRESS backing-store errors (fa | TS-08 applies only where a translation seam (EH-02) exists. mgf-livepush has no map-third-party-error-to-typed-error boundary, so TS-08 is N/A. (The suppression/fail-open paths are covered under TS-09.) |
| TS-09 | ✅ | [verify-upheld] Best-effort observers all have raising-injection tests: SlotCap.acquire fails open on incr/expire/decr raise — test_reliability.py:141-159 (parametrized over the three o | Refute attempt failed: each best-effort/suppress path has a test that injects a raiser and asserts continuation (return True / callback still fires / close() does not raise). TS-09 MUST met. UPHELD. |
| TS-10 | ✅ | SECURITY.md ships SC-* rules (slot caps as DoS backpressure, no secret leakage). There is no tests/unit/security/ directory and no negative-pattern grep pin (e.g. asserting no shell=Tru | TS-10 MUST: every security-relevant SC-* rule is pinned by a test where mechanically possible (negative case / forbidden pattern absent in src/). The DoS-via-slotcap behavior is pinned in effect, but there is no dedicated security — FIXED 2026-06-08: tests/unit/test_forbidden_patterns.py (eval/exec/shell/weak-hash/pickle grep-pin) |
| TS-11 | N/A | mgf-livepush is a pure-async library with no GUI and no PySide6/QThread workers (no pytest-qt dep; no QThread/CoreWorker in src/). The shape note confirms PR-03/04/05 N/A (no GUI). | TS-11 governs GUI workers (success path + untyped-exception path firing error signal + crash report). There are no GUI workers, so TS-11 is N/A. |
| TS-12 | ✅ | [verify-upheld] asyncio_mode="auto" (pyproject.toml:111) + pytest-asyncio>=0.23 (line 43); nearly all tests are async coroutines run by the plugin. Cancellation/DP-09 is genuinely pinne | Refute attempt (does a disconnect leak a task/slot/sub?) failed: both cancellation tests assert the subscription is closed and the slot counter returns to 0 after cancel, and they drive the real _event_gen finally branch — not a r |
| TS-13 | N/A | No round-tripping data path exists in src/ (no parse/serialise, encode/decode, save/load). The closest is SSE framing (b'data: '+data+b'\n\n' in _sse.py:108) and payload str→bytes encod | TS-13 MUST applies to code that round-trips data (f(g(x))==x). mgf-livepush has no such invertible serialize/deserialize surface, so property/round-trip tests are not required — N/A. |
| TS-14 | N/A | No PERFORMANCE.md latency/throughput budget is defined for any mgf-livepush surface, and no @pytest.mark.perf benchmark exists (the perf marker is registered+excluded at pyproject.toml: | TS-14 MUST: performance budgets MUST be pinned by a benchmark — but only where a budget exists. mgf-livepush declares no perf budget, so there is nothing to pin; the perf marker is registered per TS-19. N/A (no owned budget). |
| TS-15 | N/A | There is no real-backend smoke layer (no @pytest.mark.live/realbackend test, no env-gated real-Redis smoke). The whole suite runs against in-process doubles. | TS-15 governs OPT-IN real-backend smoke tests ('MUST be opt-in ... read-only by default'). It does not REQUIRE a real-backend smoke test to exist; it constrains them if present. None exist here, so there is nothing to violate — N/ |
| TS-16 | ✅ | [verify-upheld] Non-obvious concurrency/leak asserts carry explanatory f-strings/messages: test_reliability.py:83 `assert granted <= cap_n, f"oversell: {granted} grants for cap={cap_n}" | Refute attempt failed: the ambiguous concurrency/oversell asserts carry context messages; the rest are self-evident equality/identity checks. TS-16 MUST (self-explanatory failures) met. UPHELD. |
| TS-17 | ✅ | [verify-upheld] Shared fixtures (fake_redis/broker/slot_cap + the FakeRedis double) live in tests/conftest.py:8-46, visible to all test files via the conftest hierarchy. The only cross- | Refute attempt failed: no fixture is imported across packages at runtime; the FakeRedis reference is type-only. TS-17 MUST (fixtures discoverable via conftest, never imported across packages) met. UPHELD. |
| TS-18 | ✅ | [verify-upheld] summary.md: full 30-test run = 0.44s; no individual test approaches 1s (run.jsonl durations are 0 ms). The slow marker is registered (pyproject.toml:139) and default-exc | Refute attempt failed: no test exceeds 1s so none must be marked @pytest.mark.slow; the marker is defensively registered and excluded per TS-19. TS-18 MUST met (vacuously-true + mechanism in place). UPHELD. |
| TS-19 | ✅ | [verify-upheld] pyproject.toml:126-140 registers the full 13-marker federation taxonomy with tier annotations (smoke→0; contract/property/regression/fuzz→1; concurrency/conformance/use_ | Refute attempt failed: every marker the tests use is declared, and both axes (layer + orthogonal) plus a defensively-registered slow are present. TS-19 MUST met. UPHELD. |
| TS-20 | ✅ | Tests are NOT partitioned across the four canonical directories: there is no tests/unit/, tests/integration/, tests/e2e/, or tests/smoke/ — all 5 test files sit flat at tests/ root. The | TS-20 MUST: tests partitioned across tests/unit\|integration\|e2e\|smoke with the matching pytestmark per non-unit directory. The flat layout means the directory partition does not exist (markers are applied but the canonical dire — FIXED 2026-06-08: canonical tests/{unit,smoke,integration,e2e}/ dirs (+ charters) + smoke marker |
| TS-21 | ✅ | [verify-upheld] A smoke layer exists: tests/test_smoke.py (pytestmark=pytest.mark.smoke, line 13) verifies (a) the package imports (import mgf.livepush), (b) every key name in __all__ i | TS-21 MUST: every published library has a smoke layer doing import + __all__-reachable + shortest happy path in <100ms. All three are present and fast. The file lives at tests/ root rather than tests/smoke/ (a TS-20 directory-part |
| TS-22 | ✅ | [verify-upheld] mgf-test-supervisor>=0.1.2,<0.2 is a dev dep (pyproject.toml:45) resolved from the Codeberg index (lines 183-185). The MARKER_TIER overlay is realised via tier-annotated | Refute attempt failed: the published supervisor is adopted, every test carries a tier in run.jsonl via the marker overlay, and the runner exposes tiered/budget selection. TS-22 MUST met. UPHELD. |
| TS-23 | ✅ | [verify-upheld] The suite ran under the out-of-process mgf-test-supervisor — evidenced by .gates/last-run/run.jsonl + summary.md (run_id run-20260528T112338560Z) + .gates/last-run/failu | Refute attempt: .woodpecker.yml steps invoke bare `pytest` (lines 45,52,59), NOT mtest — this weakens the IN-CI guarantee. But the supervisor harness is demonstrably present and produced the structured per-run artifacts locally, a |
| TS-24 | ✅ | [verify-upheld] .gates/last-run/run.jsonl is one JSON object per line (30 records). Each line carries the DoctorFinding mirror (code/severity/summary/detail/why/remediation) + testing f | Refute attempt failed: the file exists, is strictly one-JSON-per-line, mirrors the required schema, and schema_version is present on every record. TS-24 MUST met. UPHELD. |
| TS-25 | ✅ | [verify-upheld] .gates/quarantine.json exists (currently {} — no flakes recorded yet) and is managed by the adopted mgf-test-supervisor (mgf.test_supervisor.quarantine), which implement | Refute attempt failed: the quarantine state file is present and the supervisor implementing the policy is adopted as a dev dep, so the capability is wired even though no flake exists. (TS-25 is L2; an L1 reading would make it defe |
| TS-26 | N/A | mgf-livepush ships no compiled artifact — it is pure-Python (src/mgf/livepush/*.py, hatchling wheel of src/mgf, no native deps, no Zig/Go/Rust/C/Swift bundle). Its optional deps (redis, | TS-26 explicitly allows pure-Python libraries to declare N/A (the standard names mgf-common itself as the analogue). No built binary exists to freshness-check. N/A. |
| TS-27 | ✅ | [verify-upheld] .gates/last-run/failures/ exists (the supervisor's per-failure bundle directory) and is empty only because the last run had 0 failures (summary.md: passed 30). The bundl | Refute attempt failed: the failures/ directory is present and wired, the writing harness is adopted, and emptiness is correctly attributable to a clean run, not a missing mechanism. The bundle contract is verifiable post-hoc on a  |
| TS-28 | ⏳ | run.jsonl schema_version is "1.0.0" (< 1.1.0), and no TestRecord.perf field appears; there is no perf-summary.md, no per-test perf JSON artifact, and no perf_span usage in src/. The --p | TS-28 (L2; L1 MAY defer): per-test perf attribution opt-in via --perf with TestRecord.perf at schema ≥1.1.0 + perf-summary.md. The supervisor supplying the capability is adopted, but no perf capture has been run and the schema is  |

### API_DESIGN

| Rule | Status | Evidence | Notes |
|---|---|---|---|
| AP-01 | ✅ | [verify-upheld] src/mgf/livepush/__init__.py:25-36 declares an explicit, alphabetically-sorted, strings-only __all__ (10 names). Every internal module declares __all__ too: _broker.py:1 | AP-01 MUST (public surface enumerated explicitly via __all__ at every consumer-importable boundary) is met by direct source inspection. The smoke test pins the surface (it checks expected<=__all__, the reverse direction of a full  |
| AP-02 | ⏳ | Every public name carries a docstring (SSEStreamService/open_stream/SlotCap/Broker/Subscription/RedisBroker/MockBroker/CapExceededError/LivePushError/sse_headers/sse_streaming_response  | Not in the challenge set; derived from evidence. Docstrings present but the 'at least one usage example' clause of AP-02 is not consistently met, so partial — ⏳. |
| AP-03 | ✅ | [verify-upheld] pyproject.toml:7 version='0.1.5' (MAJOR.MINOR.PATCH). CHANGELOG.md:5-13 states the 0.x SemVer window per AP-03 with a tight-pin instruction; release history 0.1.0→0.1.5  | Package follows SemVer, sits correctly in the 0.x window, and the changelog documents the 0.x break policy. Verified directly. UPHELD; status kept ✅. |
| AP-04 | N/A | No deprecations exist through 0.1.5; CHANGELOG.md has no [Deprecated] entries and src/ contains no DeprecationWarning calls. | Not in challenge set. AP-04 (deprecation cycle) has nothing to apply to yet — N/A for the current snapshot, mirroring mgf-common's AS-IS §15 treatment. |
| AP-05 | ✅ | [verify-upheld] Keyword-only discipline confirmed in source: SSEStreamService.__init__ _sse.py:62-68 (`*, heartbeat_seconds=...`); open_stream _sse.py:73-79 fully keyword-only (`*, chan | Every optional/non-leading param is keyword-only with defaults exactly as AP-05 prescribes; signatures stable and typed. Verified. UPHELD; status kept ✅. |
| AP-06 | ✅ | [verify-upheld] Return types pinned narrowly: Broker.publish->int (_broker.py:35), Broker.subscribe->Subscription (_broker.py:39), Subscription.get_message->bytes\|None (_broker.py:22), | Return contracts are concrete and narrow; nothing over-widens or narrows at this snapshot. Verified. UPHELD; status kept ✅. |
| AP-07 | ✅ | [verify-upheld] Typed hierarchy under the project base: _errors.py:14 LivePushError(AppError), :18 CapExceededError(LivePushError), both subclassing mgf.common.exceptions.AppError (EH-0 | Public-raised exceptions subclass the project's typed hierarchy and are documented at the raising sites with their fields. Verified. UPHELD; status kept ✅. |
| AP-08 | ✅ | [verify-upheld] `grep -L 'from __future__ import annotations' src/mgf/livepush/*.py` returns empty — all 6 modules have it (__init__.py:18, _broker.py:9, _sse.py:17, _slotcap.py:12, _er | Every public module uses `from __future__ import annotations` and isolates type-only imports under TYPE_CHECKING — confirmed by grep and read. The minor inaccuracy (FA not in ruff select) does not refute the verdict since the rule |
| AP-09 | ✅ | [verify-upheld] src/mgf/livepush/py.typed exists (0-byte marker, confirmed by ls -la). pyproject.toml:51-55 `[tool.hatch.build.targets.wheel] packages=['src/mgf']` walks the tree so hat | PEP 561 py.typed marker present and shipped by the build backend. Verified by ls. UPHELD; status kept ✅. |
| AP-10 | ✅ | `ls PUBLIC_API.* docs/PUBLIC_API.*` returns no such file. No PUBLIC_API.md / PUBLIC_API.json exists at repo root or docs/. No tests/test_public_api_doc.py. | Not in challenge set; derived. AP-10 (PUBLIC_API.md contract document in sync with __all__) is unmet for a published library — ⏳ gap, not N/A (it IS a published mgf-* package with a public surface). — FIXED 2026-06-08 (0.1.6): PUBLIC_API.md lists every public name with tier + description |
| AP-11 | ✅ | No PUBLIC_API.md exists, so no per-name stability-tier column is declared. CHANGELOG documents the 0.x window but does not tier individual names. | Not in challenge set; derived. AP-11 (explicit per-name stability tiers) is unmet because its carrier document (PUBLIC_API.md, AP-10) is absent — ⏳. — FIXED 2026-06-08 (0.1.6): every public name declares a stability tier |
| AP-12 | N/A | CHANGELOG.md follows Keep a Changelog headings (0.1.0 [Added]/[Engineering]; 0.1.1 [Added]/[Notes]). No breaking changes have shipped through 0.1.5 (0.1.2-0.1.5 are pin-walks marked 'No | Not in challenge set; derived. AP-12 (breaking-change migration recipes) has no breaking change to document yet — N/A at this snapshot, mirroring mgf-common AS-IS §15. |
| AP-13 | ✅ | `grep -rn '__version__' src/` returns NOTHING — there is no __version__ attribute on the top-level package. __init__.py:25-36 declares __all__ but no __version__. pyproject.toml:7 has v | Not in challenge set; derived. AP-13 MUST ('a __version__ attribute MUST be present on the top-level package and mirror pyproject.toml::project.version') is unmet — the attribute is entirely absent. ⏳ gap. — FIXED 2026-06-08 (0.1.6): mgf.livepush.__version__ + CI tag-coherence assertion |
| AP-14 | 🚫 | An import-linter contract exists (pyproject.toml:160-173) but it is a 'forbidden' contract keeping the core free of FastAPI — NOT the AP-14 consumer/test contract that forbids importing | Not in challenge set; derived. AP-14 MUST (CI enforces via import-linter that test fixtures only touch the public surface) is unmet: the existing contract addresses a different concern and a test currently imports a private name. — DECLINED 2026-06-08 (CFM-04 §3): import-linter consumer-fixture enforcement needs an in-repo consumer harness this library lacks; the closed-box (private _ modules + the import-linter framework-forbid contract + complete __all__/PUBLIC_API.md + public-surface smoke) satisfies the intent |
| AP-15 | N/A | No backward-compatibility shims exist in src/ (no re-export modules, no DeprecationWarning, no audit-log INFO-once paths). The package is at 0.1.5 with no removed/relocated public names | Not in challenge set; derived. AP-15 (deprecated-shim warning + audit log) has no shim to apply to — N/A at this snapshot. |

### SCOPE

| Rule | Status | Evidence | Notes |
|---|---|---|---|
| SP-01 | ✅ | No project SCOPE.md or IN-scope policy list exists anywhere in the repo. `find` for *scope* returns only .venv copies of the standard itself; root has README/CONTRIBUTING/AGENTS/FEEDBAC | SP-01 requires the library to PUBLISH an explicit IN-scope list. The Public-surface table is an exports list, not a scope policy enumerating what the library deliberately ships and why (the closed-box bar). Smallest fix: add a pro — FIXED 2026-06-08: SCOPE.md §1 |
| SP-02 | ✅ | No OUT-of-scope list exists. grep across all repo *.md/*.py/*.toml (excluding .venv and the un-audited inprogress conformance scaffold) for in-scope/out-of-scope/'not ship'/'use instead | SP-02 mandates an explicit OUT-of-scope list with per-entry reasoning. Absent. Smallest fix: add a §2 OUT table to a new SCOPE.md (e.g. broker backends beyond the seam → consumer adapter; SSE auth → consumer's endpoint/mgf-fastapi — FIXED 2026-06-08: SCOPE.md §2 |
| SP-03 | ✅ | CONTRIBUTING.md:35-50 defines the PR process (file FEEDBACK, branch from main, four-gate CI, CHANGELOG [Unreleased] entry, PUBLIC_API.md delta, reviewer = federation owner) but contains | SP-03 requires every module-/top-level-function-adding PR to justify against §1/§3, with an OUT answer rejected pointing at the ecosystem solution. The PR checklist has API-surface and CHANGELOG gates but no scope-justification ga — FIXED 2026-06-08: SCOPE.md §3 |
| SP-04 | ✅ | No Adjacent-scope (§3) list exists in the repo, and no documented promotion-criterion / consumer-demand-signal policy is published. FEEDBACK.md provides the PAPER-NN intake mechanism (t | SP-04 requires Adjacent items to require a documented demand signal before promotion to IN. With neither an Adjacent list nor a promotion-criterion policy, the rule is unmet. Smallest fix: add a §3 Adjacent section to SCOPE.md who — FIXED 2026-06-08: SCOPE.md §4 (Redis-Streams/NATS/WS adjacent) |
| SP-05 | ✅ | Contingent on the OUT-of-scope list, which does not exist (see SP-02). No file cites ecosystem alternatives in a scope-policy form; README's mentions of Redis Streams/NATS (README.md:11 | SP-05 requires every OUT-of-scope cut to cite its ecosystem alternative. With no OUT list there are no cuts and thus no citations. Smallest fix folds into SP-02: when authoring the §2 OUT table, give each row a 'what to use instea — FIXED 2026-06-08: SCOPE.md §5 |
| SP-06 | ✅ | No project SCOPE.md exists, so there is no scope policy carrying a §6 versioning/revisit-cadence note. The project is pre-1.0 (pyproject.toml version = 0.1.5; git tags v0.1.0..v0.1.5 on | SP-06 mandates that the scope policy be revisited on every MAJOR release. The triggering MAJOR boundary has not happened (pre-1.0), but the scope policy that would carry the revisit discipline does not exist at all. ⏳ rather than — FIXED 2026-06-08: SCOPE.md §6 |

### WORKFLOWS

| Rule | Status | Evidence | Notes |
|---|---|---|---|
| WF-01 | ✅ | .woodpecker.yml:14-17 `when: - event: push - event: pull_request - event: manual`. Single workflow; steps lint/typecheck/test-3.11/3.12/3.13/vuln-scan/secret-scan (lines 21-79). | [verify-upheld] WF-01 requires CI on every push to a long-lived branch AND every PR. The trigger clause literally includes `event: push` and `event: pull_request` (the extra `manual` is additive, not a substitute). No local-only p |
| WF-02 | ✅ | Four gates each a separate CI step: lint = `ruff check src tests` + `lint-imports` (.woodpecker.yml:26-27); typecheck = `mypy` (line 35) config-driven [tool.mypy] packages=["mgf.livepus | [verify-upheld] All four green gates exist as discrete steps; each fails the run on non-zero exit (default Woodpecker behavior, no `\|\| true`). The import-linter contract is genuine (closed-box: _sse/_broker/_slotcap/_errors forb |
| WF-03 | ✅ | .woodpecker.yml has NO tag-driven publish step; header comment lines 5-6 explicitly say "No publish flow yet — when a release is cut, copy the tag-coherence -> smoke -> publish -> verif | mgf-livepush IS a published mgf-* package, so WF-03 (tag-driven publish to the Codeberg registry) APPLIES and is unmet — there is no `when: event: tag` publish workflow. Per the audit shape this is a ⏳ gap (missing pipeline), NOT — FIXED 2026-06-08: tag-driven Codeberg publish pipeline (.woodpecker build→tag-coherence→smoke→publish→verify-codeberg) + scripts/verify_codeberg.py; mirrors mgf-common |
| WF-04 | ✅ | No publish step exists in .woodpecker.yml, hence no `codeberg_package_token` / `from_secret` reference and no token-storage configuration at all (grep for from_secret/codeberg_package:  | WF-04 (publish credentials in the CI secret store, scoped to tag events) depends on a publish flow that does not exist yet. Since the package is published, the obligation applies once the pipeline lands; today it is an unmet ⏳ gap — FIXED 2026-06-08: tag-driven Codeberg publish pipeline (.woodpecker build→tag-coherence→smoke→publish→verify-codeberg) + scripts/verify_codeberg.py; mirrors mgf-common |
| WF-05 | ✅ | No tag-coherence check anywhere in .woodpecker.yml (no comparison of CI_COMMIT_TAG to pyproject version or __version__). The publish-flow header (lines 5-6) lists "tag-coherence" as a T | WF-05 (publish workflow verifies tag == pyproject.version == __version__ before upload) presupposes a publish workflow. None exists, so the coherence gate is absent. ⏳ gap, applies because the package publishes. — FIXED 2026-06-08: tag-driven Codeberg publish pipeline (.woodpecker build→tag-coherence→smoke→publish→verify-codeberg) + scripts/verify_codeberg.py; mirrors mgf-common |
| WF-06 | ✅ | No build/upload steps in .woodpecker.yml. Note a STALE artifact sits in dist/: mgf_livepush-0.1.4-py3-none-any.whl + .tar.gz while current version is 0.1.5 (pyproject.toml:7) — exactly  | WF-06 (the uploaded wheel MUST be freshly built in the publishing CI run) cannot be satisfied without a publish run; there is none. The drifted 0.1.4 wheel in dist/ is harmless today (no step references it) but is precisely the fo — FIXED 2026-06-08: tag-driven Codeberg publish pipeline (.woodpecker build→tag-coherence→smoke→publish→verify-codeberg) + scripts/verify_codeberg.py; mirrors mgf-common |
| WF-07 | ✅ | No pre-publish smoke step (no ephemeral venv install of a built wheel + __version__ assert) anywhere in .woodpecker.yml. Listed as a TODO at lines 5-6. | WF-07 (install the fresh wheel into an ephemeral venv, import top-level package + __version__) requires a publish flow that does not exist. ⏳ gap, applies (published package). — FIXED 2026-06-08: tag-driven Codeberg publish pipeline (.woodpecker build→tag-coherence→smoke→publish→verify-codeberg) + scripts/verify_codeberg.py; mirrors mgf-common |
| WF-08 | ✅ | No post-publish verify step (no poll of the Codeberg REST API …/api/v1/packages/magogi-admin/pypi/<name>/<version> for 200) in .woodpecker.yml. The pyproject configures the Codeberg ind | WF-08 (post-publish verification against the Codeberg registry) requires a publish flow; none exists. ⏳ gap, applies. — FIXED 2026-06-08: tag-driven Codeberg publish pipeline (.woodpecker build→tag-coherence→smoke→publish→verify-codeberg) + scripts/verify_codeberg.py; mirrors mgf-common |
| WF-09 | ✅ | .woodpecker.yml images: `python:3.12-slim` (lines 22/31/48/63), `python:3.11-slim` (41), `python:3.13-slim` (55); plugin/tool image `zricethezav/gitleaks:v8.30.1` (line 77). No `python: | [verify-upheld] WF-09 requires every external dependency pinned: interpreter images must not be `python:slim` (they are minor-pinned `python:3.X-slim`) and plugin actions must be exact-tagged (gitleaks `v8.30.1`). §7.1 explicitly  |
| WF-10 | ✅ | .woodpecker.yml steps lint/typecheck/test-3.11/test-3.12/test-3.13/vuln-scan/secret-scan (lines 21-79) declare NO `depends_on:` (grep: none). The per-version test axis is expressed as e | [verify-upheld] WF-10 requires independent steps to run in parallel and matrix axes to fan out, never serialise. Woodpecker runs steps without `depends_on` in parallel by default; nothing chains the gates or the version axis. The  |
| WF-11 | ⏳ | A `uv.lock` (193 KB) IS checked into the repo, but every CI install step uses `pip install -e ".[dev,redis,fastapi]"` (.woodpecker.yml:25/34/44/51/58/67) — i.e. resolves from pyproject. | WF-11 (a run reproducible from its inputs alone; §7.1 'CI installs from lock, not from pyproject directly') is PARTIALLY met: images are pinned, network is mocked, no host state — but the dependency layer floats because CI install |
| WF-12 | ✅ | grep for `\|\| true` / `2>/dev/null` / `; true` / `continue-on-error` over .woodpecker.yml: NO matches. Every command runs bare. The one relaxation — vuln-scan dropping `--strict` — car | [verify-upheld] WF-12 forbids silent failures (`\|\| true`, swallowed exits, no-op green ticks) and requires loud, contextual failure. No error-swallowing construct exists; non-zero exits propagate (default Woodpecker surfacing of |
| WF-13 | ✅ | .woodpecker.yml lines 1-3: `# GENERATED — do not hand-edit. Source: mgf-standard/templates/woodpecker/` | Generated artifact; header present confirming the pipeline is managed by mgf-fed. |

### RELEASING

| Rule | Status | Evidence | Notes |
|---|---|---|---|
| REL-01 | ✅ | Annotated tags v0.1.0..v0.1.5 all present (git tag -l); pyproject at 0.1.5 with matching v0.1.5 tag. | Unchanged — not among the three ✅s challenged in this refute pass. Carried through as-is. |
| REL-02 | ✅ | [verify-upheld] pyproject.toml::version = 0.1.5. dist/ contains ONLY mgf_livepush-0.1.4-py3-none-any.whl + mgf_livepush-0.1.4.tar.gz (built Jun 4) — a distinct, LOWER version, not a sam | [verify-upheld] REL-02 forbids reusing a version string across different wheel contents (rebuilding the same 0.X.Y from a later commit). Tried to refute: looked for a 0.1.5 dist artifact that could be a content-swapped rebuild, a  |
| REL-03 | N/A | Carried unchanged (not a ✅ challenged in this pass). | Unchanged — verdict not under refute scope. Kept verbatim. |
| REL-04 | ✅ | [verify-upheld] grep -rEni 'pypirc\|codeberg_package_token\|write:package\|TWINE_PASSWORD\|password=' over all *.md/*.yml/*.yaml/*.toml/*.cfg/*.env/*.ini => ZERO hits. `git ls-files \|  | [verify-upheld] REL-04 forbids tokens in chat/shell-history/env-in-unmanaged-sessions and forbids committing them. Tried hard to refute: searched every config/doc surface and the workflow file for any token, secret, or password, a |
| REL-05 | ✅ | [verify-upheld] CHANGELOG strictly increasing 0.1.0→0.1.5 with each version a single distinct ## [0.1.N] row (lines 26/35/43/52/59/75), no duplicate version rows, no delete+re-upload/co | [verify-upheld] REL-05 demands published-version immutability — fixes ship as a NEW version, never a content swap of an existing one. Tried to refute by hunting for a re-uploaded/swapped same-version (duplicated CHANGELOG row, del |
| REL-06 | ✅ | Carried unchanged (not a ✅ challenged in this pass). | Unchanged — not under refute scope. Kept as-is. — FIXED 2026-06-08: tag→build→tag-coherence(pyproject+__version__)→smoke→publish→verify, in order |
| REL-07 | N/A | Carried unchanged (not a ✅ challenged in this pass). | Unchanged — not under refute scope. Kept as-is. |
| REL-08 | ✅ | Carried unchanged (not a ✅ challenged in this pass). | Unchanged — not under refute scope. Kept as-is. — FIXED 2026-06-08: the smoke step installs the built wheel into a fresh venv + imports mgf.livepush before publish |
| REL-09 | N/A | Carried unchanged (not a ✅ challenged in this pass). | Unchanged — not under refute scope. Kept as-is. |

### PACKAGE_DISTRIBUTION

| Rule | Status | Evidence | Notes |
|---|---|---|---|
| PKG-01 | ✅ | [verify-upheld] pyproject.toml:178-185 [[tool.uv.index]] name='codeberg-mgf' url='https://codeberg.org/api/packages/magogi-admin/pypi/simple/' explicit=true; [tool.uv.sources] maps mgf- | Tried to refute by grepping for any mgf-* dependency resolving from pypi.org: none. Every mgf-* dep (mgf-common, mgf-test-supervisor) is pinned to the Codeberg index in both pyproject and the resolved lock. The package's own publi |
| PKG-02 | ✅ | [verify-upheld] The only registry endpoint in committed config is pyproject.toml:180 url='https://codeberg.org/api/packages/magogi-admin/pypi/simple/' — the verbatim §3 canonical simple | Refute attempt: looked for a malformed/variant endpoint (missing /simple/, wrong owner, /api/v1 confusion in resolution config) — none. Upload/REST endpoints are absent only because there is no publish pipeline (a PKG-04/09 gap),  |
| PKG-03 | ✅ | [verify-upheld] .woodpecker.yml contains no plaintext token and no OIDC/Trusted-Publisher reference; there is no publish step at all (header comment: 'No publish flow yet'). A secret-sc | Refute attempt: searched committed config for any pasted token / OIDC ref / pypa-publish action — none exist. Token-in-CI-secret model isn't wired only because the publish pipeline is absent (PKG-09 gap), which is not a PKG-03 aut |
| PKG-04 | ✅ | .woodpecker.yml has no publish flow ('No publish flow yet — when a release is cut, copy the tag-coherence -> smoke -> publish -> verify-pypi chain from mgf-common'). dist/ holds only st | Unmet gap (no publish pipeline), not a deliberate decline — ⏳ per the prompt's gap convention. — FIXED 2026-06-08: the tag-gated build→...→publish chain is the ordered Codeberg publish ritual |
| PKG-05 | ✅ | No verify-codeberg step exists in .woodpecker.yml; the comment even names the legacy 'verify-pypi' as the to-be-copied step. No post-publish REST-200 gate is present. | Unmet gap — the verification step is simply absent because there is no publish pipeline. ⏳. — FIXED 2026-06-08: the verify-codeberg step polls the Codeberg REST API post-publish |
| PKG-06 | ✅ | [verify-upheld] pyproject.toml:178-185 — named index 'codeberg-mgf' with explicit=true + [tool.uv.sources] mapping for EVERY mgf-* dependency (mgf-common, mgf-test-supervisor). No bare  | Refute attempt: looked for an uncovered mgf-* dependency (mapped index but missing from [tool.uv.sources], or a committed bare extra-index-url) — both mgf-* deps are mapped, explicit=true present, no bare form. Upheld. |
| PKG-07 | N/A | Immutability/re-upload policy governs a publish session; no publish pipeline or release session exists here, and no delete+re-upload has occurred. CHANGELOG records no botched-upload re | No release session to which the re-upload/immutability discipline applies in committed config — N/A for this leaf at its current pre-publish-pipeline state. |
| PKG-08 | N/A | Retention/quota is a registry-account-level operational policy (the magogi-admin account quota + a prune job), not a per-leaf-repo artifact. No retention surface lives in a consumer/sib | Account-wide registry hygiene owned centrally; not bindable in this leaf's committed config. N/A. |
| PKG-09 | ✅ | .woodpecker.yml has no tag-driven publish: `when:` triggers are push/pull_request/manual only, and no step is event:tag scoped. The header explicitly defers the publish chain. No codebe | Unmet gap — CI tag-driven publish is not yet wired. ⏳ (this IS a published mgf-* package, so the publish-chain rules are gaps, not N/A). — FIXED 2026-06-08: tag-driven, build-in-CI, secret-token Codeberg publish step added |
| PKG-10 | ✅ | [verify-upheld] pyproject.toml:6 name='mgf-livepush' (hyphenated dist name); :51-55 [tool.hatch.build.targets.wheel] packages=['src/mgf'] ships the PEP 420 namespaced import mgf.livepus | Refute attempt: checked for a non-PEP-503-normalizable name or a non-namespaced/top-level-__init__ import — none; the build deliberately omits a top-level __init__ to keep mgf.livepush a sibling. No pypi.org/project/<name> canonic |
| PKG-11 | N/A | PKG-11 binds an agent/federation tool that recommends based on a sibling's published version (e.g. mgf-common's standards/agents CLI version-check logic). mgf-livepush is a consumer lib | No agent version-check surface in this repo to target at Codeberg vs pypi.org. N/A for this leaf. |
| PKG-12 | ✅ | [verify-upheld] Full-tree grep for pypi.org returns exactly ONE hit: SECURITY.md:3, a markdown link to the third-party sibling mgf-common's project page — a permitted (a) third-party /  | Refute attempt: hunted for any residual pypi.org publish/distribution surface for an mgf-* package — the sole hit is an allowlisted third-party doc link. Caveat: the no-pypi-surface CI grep gate (the mgf-common cornerstone templat |

### DOCUMENTATION

| Rule | Status | Evidence | Notes |
|---|---|---|---|
| DOC-01 | ✅ | All 11 universal 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) + do | DOC-01 §2.0.1: PUBLIC_API.md/.json are a MUST for cornerstone+sibling (only apps are exempt). mgf-livepush is a published sibling, so the ten-doc baseline IS satisfied but the library-only PUBLIC_API.{md,json} pair is missing — ma — FIXED 2026-06-08 (0.1.6): PUBLIC_API.md + PUBLIC_API.json companion now exist at root |
| DOC-02 | ✅ | docs/ exists with only two buckets: docs/claude/ (CLAUDE.md) and docs/inprogress/ (MGF_STANDARDS_CONFORMANCE.md). No docs/standards/ (find returns nothing) and no docs/cutover/ (ls: No  | Per §2.0.2 a sibling MUST ship docs/standards/ as a pointer-only README (§2.0.4) and docs/cutover/ (✅ for sibling, empty until first breaking change). Both buckets are absent. The claude/ + inprogress/ buckets present are correct — FIXED 2026-06-08: docs/standards/ (pointer-only README) + docs/cutover/ + docs/reference/ buckets added (Sibling minimum-set) |
| DOC-03 | ✅ | find docs -name README.md returns NOTHING. docs/claude/ holds only CLAUDE.md; docs/inprogress/ holds only MGF_STANDARDS_CONFORMANCE.md. Neither long-lived bucket has its own charter REA | DOC-03: every long-lived bucket MUST have its own README.md stating the charter + one-line description of each file. Both shipped buckets (claude/, inprogress/) lack one. Smallest fix: add docs/claude/README.md and docs/inprogress — FIXED 2026-06-08: every docs/ bucket now carries a README.md charter |
| DOC-04 | ✅ | CHANGELOG.md:5 cites Keep a Changelog v1.1.0; [Unreleased] at line 20; dated per-release entries 0.1.0 (lines 75-126) through 0.1.5 (line 26) with Added/Engineering subsections. The 0.1 | [verify-upheld] CHANGELOG is well-formed Keep-a-Changelog with [Unreleased] + dated entries, and the maiden entry's documented surface matches the public symbols. DOC-04's same-commit clause cannot be retro-disproven from the tree |
| DOC-05 | N/A | CHANGELOG.md entries 0.1.1→0.1.5 are all additive or pin-walks: 0.1.2/0.1.3/0.1.4/0.1.5 each state 'No API change' / 'pin widened'; 0.1.0 is the maiden additive surface. No 'Removed'/'C | DOC-05's premise binds only on a breaking change (MAJOR, or MINOR within 0.x per AP-03 that removes/renames/reshapes a name). mgf-livepush has shipped no breaking change — every release is additive or a dependency-pin walk — so no |
| DOC-06 | N/A | docs/inprogress/ contains only MGF_STANDARDS_CONFORMANCE.md (a conformance ledger governed by CFM-03/DOC-15, not the generic priority-tracker shape). No RA/SH/PC-style living priority t | DOC-06 binds when a project ships a LIVING PRIORITY TRACKER; it dictates that tracker's shape. This sibling ships none (per §2.0.2 a sibling has docs/inprogress/ only 'if has parallel work streams'). With no priority tracker prese |
| DOC-07 | ✅ | docs/claude/CLAUDE.md exists (12417 bytes), dense-lookup: standards topic table (lines 43-53), top-30 rules inline (lines 56-167), bootstrap snippet (lines 170-201), four green gates (l | [verify-upheld] The mandatory §4 CLAUDE.md ships in dense-lookup format with no marketing prose — DOC-07's bar (presence + dense-lookup format) is met. Caveat (not a refutation): the §4-named sections File map / Cross-cutting patt |
| DOC-08 | ✅ | No PUBLIC_API.md or PUBLIC_API.json at repo root (find . -name 'PUBLIC_API*' empty); src/mgf/livepush/__init__.py:25 defines __all__ but nothing tracks it. README.md:67 'Public surface' | DOC-08: PUBLIC_API.md MUST track __all__, the PUBLIC_API.json companion MUST be generated from __all__ at every release and pinned in CI against PUBLIC_API.md (two pins). For this published sibling neither doc exists and no CI pin — FIXED 2026-06-08 (0.1.6): PUBLIC_API.json + generator + pin test |
| DOC-09 | ✅ | .woodpecker.yml steps are lint/typecheck/test-3.11-13/vuln-scan/secret-scan — no drift-lint that verifies named symbols exist, and no PUBLIC_API pin. README.md:67-77 and STARTHERE.md:43 | DOC-09: docs that name code MUST be drift-detected — either (a) a CI lint verifying the referenced name exists (canonical for PUBLIC_API.md) or (b) a back-reference in the named code. Neither direction is wired: no drift CI step, — FIXED 2026-06-08 (0.1.6): md↔__all__ name-existence pin test |
| DOC-10 | ✅ | FEEDBACK.md is the consumer flow: §1 Process with OPEN → SHIPPED/DEFERRED/WONTFIX/MOVED lifecycle (lines 30-34), severity tags 🟢/🟡/🔴 in the template (lines 47-48), and §2 holds no paper | [verify-upheld] The consumer-facing flow and internal posture are cleanly separated with non-overlapping content, exactly DOC-10's split (standard line 35). No cross-contamination found. |
| DOC-11 | ✅ | docs/inprogress/ holds one tracker, MGF_STANDARDS_CONFORMANCE.md, status 'v0.1 — initial tracker' (line 3); counts table rows read '(set on first depth audit)' and most family rows say  | [verify-upheld] DOC-11 (standard line 36) triggers archival only for a tracker fully-closed for one release cycle. This tracker is explicitly open/initial, so no archival is owed. Upheld. |
| DOC-12 | ✅ | In-repo file refs are relative: STARTHERE.md:72 → docs/inprogress/MGF_STANDARDS_CONFORMANCE.md, conformance tracker → ../../README.md and ../../CHANGELOG.md, STARTHERE Quick-links table | [verify-upheld] Tried to refute by grepping for absolute links to mgf-livepush's own repo: the only two hits are the Codeberg issues tracker and Security-tab web-UI features, which cannot be relative file links — legitimately abso |
| DOC-13 | ✅ | FEEDBACK.md header (lines 6-12) routes mgf-livepush-specific signals HERE and federation-wide signals to mgf-common/FEEDBACK.md; FB-01 local numbering stated (lines 14-17) and reinforce | [verify-upheld] FEEDBACK.md is correctly repo-scoped with explicit routing and FB-01 numbering discipline, satisfying DOC-13 (standard line 38). No counterexample. |
| DOC-14 | N/A | MGF_STANDARDS_CONFORMANCE.md §1 declares 'federation sibling'; pyproject.toml:31 pins mgf-common>=0.41,<0.47; the project's own ledger row at MGF_STANDARDS_CONFORMANCE.md:580 marks DOC- | DOC-14 (MGF_ADOPTION.md) applies to CONSUMER APPLICATIONS only; ADP-04 carves out federation siblings — their adoption relationship lives in mgf-common's federation_roadmap.md + their own CHANGELOG. mgf-livepush is a sibling, so t |
| DOC-15 | ✅ | docs/inprogress/MGF_STANDARDS_CONFORMANCE.md exists at the canonical path; §1 (line 28) declares 'Declared conformance level: L2 (per CFM-02)'; the ledger uses ✅/🚫/⏳/N/A markers and acc | DOC-15's literal MUSTs are met: the conformance tracker exists at docs/inprogress/MGF_STANDARDS_CONFORMANCE.md, declares L1/L2/L3 (L2), uses the four markers, and the CFM-03 completeness gate is satisfied (every Index-of-MUSTs id  |
| DOC-16 | ✅ | DEPS.md at repo root, bidirectional: §1 'What mgf-livepush depends on' (mgf-common runtime + redis/fastapi extras table, lines 16-20) and §2 'Who depends on mgf-livepush' (PlasmaMapper, | [verify-upheld] DEPS.md is present and structurally bidirectional per DOC-16 v2.12 (standard line 41): §1 outbound deps + §2 inbound consumers with import-site coupling proxy + a verification method. The §1 '>=0.41,<0.42' pin is s |
| DOC-17 | ✅ | FEDERATION.md is a pointer stub: states 'The federation contract is not maintained here — there is one canonical copy' and links to mgf-standard's FEDERATION.md as single source of  | [verify-upheld] Per DOC-17 (standard line 42), every non-mgf-standard project ships FEDERATION.md as a pointer stub linking the canonical contract. mgf-livepush does exactly that. Upheld. |
| DOC-18 | ✅ | pyproject.toml:31 pins 'mgf-common>=0.41,<0.47' (walked across 0.1.2→0.1.5 per CHANGELOG: <0.43→<0.45→<0.46→<0.47), but the coupled DEPS.md §1 row (DEPS.md:18) still reads 'mgf-common > | DOC-18 (ripple rule): a change to a coupled surface MUST update its dependents in the same commit; DEPS.md §1 is an explicitly coupled dependent of the pyproject pin. The mgf-common ceiling moved 0.42→0.47 in pyproject but DEPS.md — FIXED 2026-06-08: DEPS.md mgf-common pin synced >=0.41,<0.42 → >=0.41,<0.47 |
| DOC-19 | ✅ | LESSON_LEARNED.md present at repo root (954 bytes), DOC-19 shape: append-only/newest-first header citing DOC-19 + the template (lines 3-6), and a dated seed entry '2026-06-07 — File see | [verify-upheld] DOC-19 (MUST since v2.21, standard line 44 + §2.0.1 matrix line 167) requires presence of a root LESSON_LEARNED.md; a seeded file with no real lessons yet is explicitly conformant ('presence is the bar'). The file  |

### OPERABILITY

| Rule | Status | Evidence | Notes |
|---|---|---|---|
| OP-01 | N/A | pyproject.toml has no [project.scripts]/console-scripts (grep returned nothing); no __version__ in src/mgf/livepush/*.py (grep for __version__ empty); no service runtime / HTTP /version | OP-01 ('the APP MUST report its rich version on demand' via CLI --version or service /version) binds an app/CLI/service with an executable identity surface. mgf-livepush is a pure consumer library (no CLI of its own, no standalone |
| OP-02 | N/A | No [project.scripts] entry point (pyproject grep empty); no doctor command in src/mgf/livepush/ (only _broker/_sse/_slotcap/_errors/fastapi modules + __init__). The package ships no CLI | OP-02 ('every project MUST ship a doctor self-diagnostic command' probing the app's own config validity / persistent stores / invariants) presupposes an app with its own state and a CLI to run the command from. mgf-livepush is a l |
| OP-03 | N/A | pyproject.toml has NO [project.urls] table (grep 'project.urls' found only the [project] header at line 5; the only 'url=' is the uv index at tool.uv.index). No CLI exists, so no --help | OP-03's MUST clause is 'pyproject.toml's Homepage/Documentation/Issues URLs, and every URL printed in --help footers/CLI errors/GUI menu items, MUST point at the real repo'. mgf-livepush declares NO Homepage/Documentation/Issues U |
| OP-04 | ✅ | Stale dep-pin headline fact: pyproject.toml line 'dependencies = ["mgf-common>=0.41,<0.47"]' and CHANGELOG.md [0.1.5] ('Walk the mgf-common pin ceiling <0.46 -> <0.47') vs DEPS.md line  | OP-04 ('headline facts in README/STARTHERE/front-matter MUST match reality'; the example given is exactly 'a mgf-common = 0.25,<0.26 pin in README when reality is 0.33,<0.34'). DEPS.md §1 records the runtime dep window as >=0.41,< — FIXED 2026-06-08 (0.1.6): the PUBLIC_API.md that README/STARTHERE link to now exists (dangling headline reference resolved); DEPS pin synced |
| OP-05 | N/A | No CLI ([project.scripts] empty) and no service runtime. SSEStreamService.__init__ (_sse.py:62-71) takes broker/slot_cap/heartbeat_seconds as constructor args supplied by the consuming  | OP-05 ('the active configuration MUST be inspectable from a running app' via `<app> explain` or an admin /config endpoint) binds an app that loads and owns a configuration. mgf-livepush is a library whose 'config' is just construc |
| OP-06 | N/A | The library logs via stdlib loggers it does not own the sink for: _sse.py:35 `LOG = logging.getLogger(__name__)` and _slotcap.py:22 same; _slotcap.py:60-68 / 83-90 emit LOG.warning with | OP-06 ('recent logs MUST be accessible without source-tree knowledge' via `<app> logs` / GUI View Logs / a service aggregator URL) binds the component that OWNS the log sink and operator UX. A library writes to the consumer-config |
| OP-07 | N/A | No CLI ([project.scripts] empty), no bundle/diagnostic-tarball code anywhere in src/mgf/livepush/, no crash-report directory or config snapshot owned by the library. | OP-07 ('every project MUST ship a bundle/diagnostic-tarball command' = redacted config + last N log lines + crash reports + doctor output + system info) presupposes an app that owns config, logs, crash reports and a doctor — none  |
| OP-08 | N/A | No on-disk state owned by the library: no crash-report dir, no log file/RotatingFileHandler, no cache dir in src/mgf/livepush/. The one unbounded-resource surface — Redis slot counters  | OP-08 ('state DIRECTORIES MUST have bounded growth' — crash reports, log rotations, caches, with the 'fills the user's disk over a weekend' failure mode) binds a component that writes growing on-disk state. mgf-livepush writes no  |
| OP-09 | N/A | Marked 'service' in the OPERABILITY.md rules box (line 42). No deployment/runtime: no Dockerfile, no compose/k8s manifest, no environment=production config validator (find for compose/k | OP-09 ('production safety guards MUST refuse dev-shaped values' during config validation before listening) is explicitly service-only and binds a deployed service that loads an environment + validates it. mgf-livepush is a library |
| OP-10 | N/A | 'service' rule (OPERABILITY.md line 43). No deployable artefact owned by this repo: no Dockerfile / image / compose / k8s manifest (find returned none); the only build artefacts are the | OP-10 ('every deployable artefact MUST carry a stable version tag; image:latest forbidden; rollback runbook') binds a deployed service producing container/VM images. mgf-livepush ships a versioned Python package, not a deployed im |
| OP-11 | N/A | 'service' rule (OPERABILITY.md line 44). No alerting surface in the repo: no Prometheus rules, no alertmanager config, no docs/runbooks/ (find for alert/runbook returned nothing under t | OP-11 ('every alert MUST reach a human + link a runbook; paging path wired + synthetic-alert tested') binds a deployed service with an alerting stack. A library has no alert rules, no alertmanager, no on-call. Observability hooks  |
| OP-12 | N/A | 'service' rule (OPERABILITY.md line 45). No backup/restore surface: no backup script, no docs/drills/, no S3/R2/GCS target, no persistent datastore owned by the library (find for backup | OP-12 ('backup + restore MUST be exercised end-to-end against the real target') binds a service that owns durable state needing disaster recovery. mgf-livepush persists nothing of its own (transient streaming + TTL'd counters), so |

### DEPLOYMENT

| Rule | Status | Evidence | Notes |
|---|---|---|---|
| DEP-01 | N/A | DEPLOYMENT.md:7-18 scopes this standard to "stateful web-service consumer applications"; line 20-21 puts "Federation libraries (no runtime)" OUT of scope. The DEP-01 rules-box row (line | DEP-01 requires every cloud resource (VM, LB, bucket, DNS, cert) to be declared in IaC. A library owns no cloud infrastructure — there is nothing to declare. The premise (a deployed service provisioning cloud infra) genuinely does |
| DEP-02 | N/A | DEPLOYMENT.md:42 "Applies to: service"; scope clause lines 7-21 exclude no-runtime federation libraries. No production VM, no ansible/, no container image owned by this package (filesys | DEP-02 governs config-as-code for VM/container state on a production host. A library installs no packages on a VM and configures no systemd units; it has no host state to manage. Doesn't bind a library. |
| DEP-03 | N/A | DEPLOYMENT.md:43 "Applies to: service". This rule governs the deploy step of a service (no pip --upgrade at runtime in production, install only from a lock at deploy time). mgf-livepush | DEP-03 is about immutable release ARTEFACTS of a running service deployed onto servers — the deploy installs from a lock with no index lookup. A library is itself a dependency; PACKAGE_DISTRIBUTION/RELEASING (PKG/REL) govern how t |
| DEP-04 | N/A | DEPLOYMENT.md:44 "Applies to: service". DEP-04 governs PRODUCTION secrets (DB creds, signing keys, TLS private keys) of a deployed service stored in vault/KMS outside the repo. mgf-live | A library has no production deployment and therefore no production secrets to encrypt at rest. The premise (a service with DB/API/TLS secrets) does not bind a library. SC-01 secret-handling-in-code is a SECURITY-family concern, se |
| DEP-05 | N/A | DEPLOYMENT.md:45 "Applies to: service". DEP-05 requires deploy/backup/restore/rollback SCRIPTS to be environment-explicit. mgf-livepush has no deploy/scripts/ (no deploy/ directory at a | There are no deploy commands for a library — nothing is rolled out to an environment. The env-explicit-deploy-script premise does not bind a library. The .woodpecker.yml is a CI publish/test pipeline (a RELEASING/WF concern), not  |
| DEP-06 | N/A | DEPLOYMENT.md:46 "Applies to: service". DEP-06 requires every RELEASE of a deployed service to have a drill-measured, bounded rollback runbook (blue/green, symlink-swap, snapshot-restor | Reversible deploys of a running production service do not apply to a library. A library release is rolled back at the consumer's lock-pin level (REL/PKG version-immutability), not via a service rollback runbook. The premise does n |
| DEP-07 | N/A | DEPLOYMENT.md:47 "Applies to: service". DEP-07 mandates a top-level deploy/ directory (README, terraform/, ansible/, scripts/, monitoring/, docs/) for "every web-service consumer". File | The deploy/ directory shape is required for web-service consumer applications, explicitly NOT for no-runtime federation siblings (lines 20-21, 199-209). A library legitimately has no deploy/ directory; the premise does not bind it |
| DEP-08 | N/A | DEPLOYMENT.md:48 "Applies to: service". DEP-08 requires PRODUCTION to export metrics/logs/traces to a queryable sink plus a committed deploy/docs/slo.md and human-paging alerts. mgf-liv | End-to-end production observability (sink, SLO file, burn-rate alerts paging humans) is a property of a deployed service. A library has no production to observe; the operator/consumer owns DEP-08. The library's own logging is an i |
| DEP-09 | N/A | DEPLOYMENT.md:49 "Applies to: service". DEP-09 requires DNS records in IaC/committed list and auto-renewing TLS certs with expiry monitoring. mgf-livepush owns no DNS records, no domain | A library has no DNS or TLS to manage — it serves no hostname. The managed-DNS/TLS premise does not bind a library; the consumer that mounts the fastapi.py SSE endpoint owns its host's DNS+TLS. |
| DEP-10 | N/A | DEPLOYMENT.md:50 "Applies to: service". DEP-10 requires deploy/docs/first-production-cut.md documenting the green-field provisioning sequence (IaC applies, config playbooks) of a servic | There is no green-field production cut for a library; it is published to a registry, not provisioned onto servers. The first-production-cut-runbook premise does not bind a library. |
| DEP-11 | N/A | DEPLOYMENT.md:51 "Applies to: service". DEP-11 requires deployability to >=2 environments (prod + staging/dev) from the same IaC+config code, parameterised by an env file. mgf-livepush  | A library is not deployed to multiple service environments; it is a dependency consumed identically everywhere. The multi-environment-from-same-code premise does not bind a library. Its consumers own DEP-11 for their own deploymen |

### PRESENTATION_LAYER

| Rule | Status | Evidence | Notes |
|---|---|---|---|
| PR-01 | ✅ | src/mgf/livepush/fastapi.py:14-18 (TYPE_CHECKING-only fastapi imports) + :35-36 (function-local `from fastapi import HTTPException` / `StreamingResponse`); grep over src/ confirms the O | [verify-upheld] PR-01's binding MUST clauses — 'MUST NOT import any UI framework at module level anywhere under the SDK's import root' AND 'MUST be enforced mechanically via import-linter' — are both met. Refute attempts failed: ( |
| PR-02 | N/A | mgf-livepush is a published library/SDK (no GUI, no CLI of its own); PRESENTATION_LAYER.md PR-02 ('activates at the second UI consumer') + §8.2 ('PR-02..PR-07 are N/A until a multi-UI c | No second UI consumer exists. PR-02 is dormant until the SDK grows a dedicated multi-UI app repo, so it is correctly N/A per §8.2. (Verdict derived independently; the prompt supplied only PR-01 to challenge.) |
| PR-03 | N/A | No <sibling>-app repo with multiple UIs exists; PR-07/§8.2 permit a pure-SDK sibling with zero UI consumers to mark PR-02..PR-05 N/A. The repo is src/mgf/livepush/* (6 modules) — a libr | The three-layer app split applies only inside an app repo with UI-framework code. mgf-livepush is the SDK side, so PR-03 is N/A (rule activates at the first UI consumer per §7 'For a sibling without an app today'). |
| PR-04 | N/A | PR-04 governs the app-side layer hierarchy (core/view vs ui/<framework>). No app repo / multi-UI tree exists. The SDK-side mechanical enforcement that DOES exist is the PR-01 import-lin | PR-04's two-contract app-layer enforcement has no subject here (no core/view/ui tree). N/A per §8.2; the live import-linter enforcement maps to PR-01, already credited there. |
| PR-05 | N/A | PR-05 (sibling ui/<framework>/ adapters MUST consume view/ only, never a peer ui/) requires ≥2 UI adapters. mgf-livepush ships exactly one optional adapter (fastapi.py) and no app repo. | Only one UI adapter exists, so there is no peer-UI to import; PR-05 is structurally inapplicable and correctly N/A per §8.2. |

### AGENTS

| Rule | Status | Evidence | Notes |
|---|---|---|---|
| AG-01 | ✅ | [verify-upheld] /home/bassam/PycharmProjects/mgf-livepush/AGENTS.md present at repo root; `diff AGENTS.md /home/bassam/PycharmProjects/mgf-common/AGENTS.md` exits 0 (byte-identical to f | [verify-upheld] Every clause met: file exists at root, identical-to-template, thin-pointer not a briefing, project notes in docs/claude/CLAUDE.md. Refute failed — diff genuinely empty, no briefing leak. |
| AG-02 | ✅ | [verify-upheld] AGENTS.md line 9 points at the single source `mgf-common agents`; line 36 'One message for the whole federation; no per-project variant.' Project lookup lives in docs/cl | [verify-upheld] Canonical briefing deferred to the CLI; project lookup in the catch-up-managed CLAUDE.md auto-block. No drift-prone local copy. Refute failed. |
| AG-03 | ✅ | [verify-upheld] Agent commits dd18c4d/f0bc43b/5aca44c/cc0f9367 each carry BOTH trailers ('Signed-off-by: Bassam Alsanie <bassam@magogi.org>' + 'Co-Authored-By: Claude Opus 4.8 (1M conte | [verify-upheld] Both trailers present on agent commits and enforced via committed .gitmessage; canonical bassam@magogi.org identity in current convention. The gmail-signed commit is pre-canonical and d013a10 is a merge commit — ne |
| AG-04 | ✅ | [verify-upheld] FEEDBACK.md exists with §1 Process, §2 paper template (lines 42-60), §4 submission flow. CLAUDE.md feedback-discipline auto-block (BEGIN line 228 / END line 257) directs | [verify-upheld] AG-04 is an agent-conduct/review-only rule (§9); the repo supplies FEEDBACK.md + the catch-up directive making 'file a paper' the default, with no buried workarounds in source. Refute failed. |
| AG-05 | N/A | AGENTS.md:9 ("Run mgf-common agents and do exactly what it prints"); AGENTS.md:1-5 thin-pointer managed by catch-up | AG-05 ("Agents MUST verify memory claims before recommending action") is a runtime/session discipline rule binding the *agent working in the repo*, not a checkable artifact a published library ships. Per the standard's own §9 Mech |
| AG-06 | N/A | .claude/settings.json present (harness permission rules live here); standard §9: "AG-06 \| Runtime / harness enforcement (permission prompts on Bash, MCP tool calls). Not a code rule." | AG-06 ("Risky operations MUST require explicit confirmation") is explicitly a runtime/harness rule, "Not a code rule" per §9. It governs the agent's behavior during a session, not any artifact a published library ships. No file:li |
| AG-07 | N/A | Standard §9: "AG-07 \| Self-enforcement; runtime reminders surface stale task lists." | AG-07 ("Agents MUST use TaskCreate/TaskUpdate for work spanning ≥3 steps") binds the agent's in-session task-tracking, enforced by runtime reminders. It is not a library artifact: a published sibling neither creates nor ships task |
| AG-08 | N/A | Standard §5 + §9: "AG-08 \| Self-enforcement; runtime auto-memory rules cover this." | AG-08 ("Memory writes MUST be federation-scoped, not session-scoped") governs the agent's auto-memory subsystem, not any artifact the library publishes. There is no file in mgf-livepush that holds federation memory; memory lives i |
| AG-09 | N/A | pyproject.toml:178-185 declares the Codeberg registry as the source for mgf-* siblings (the contract AG-09 names); standard §9: "AG-09 \| Review-only." | AG-09 ("verify a sibling's published version against the Codeberg registry, not local dist/") is a review-only agent-action rule for the moment an agent recommends a version pin. It is not a static library artifact. The repo does  |
| AG-10 | N/A | FEEDBACK.md present at repo root (the channel AG-10 routes to); standard §7 + §9: "AG-10 \| Review-only." | AG-10 ("standards drift caught by an agent MUST be filed as a PAPER, not silently fixed") is a review-only rule binding the agent's response to drift it discovers. It is not a library artifact whose presence/absence is checkable;  |
| AG-11 | ✅ | [verify-upheld] FEEDBACK.md header 'Where to file what' (line 7) splits mgf-livepush-specific → file HERE (line 9) vs federation-wide → mgf-common/FEEDBACK.md (lines 10-12). CLAUDE.md f | [verify-upheld] Routing substrate present and correct, including the 'enough to triage and act' template shape AG-11 mandates. Prompt cited CLAUDE.md:233-247 but content is at 232-241 — immaterial line-number rounding. Refute fail |
| AG-12 | ✅ | [verify-upheld] Project-scoped content lives in /home/bassam/PycharmProjects/mgf-livepush/docs/claude/CLAUDE.md (the path `--project` reads, AGENTS.md fallback). mgf-common is a hard ru | [verify-upheld] The uniform `--project` capability comes from the installed mgf-common CLI plus the present docs/claude/CLAUDE.md content; no bespoke command needed. Refute failed. |
| AG-13 | N/A | FEEDBACK.md present at repo root (the request channel AG-13 names); pyproject.toml:6 name="mgf-livepush" — a library, not the mgf-common supervisor. | AG-13 ("only the mgf-common supervisor may change a library; others file in the target's FEEDBACK.md") is a federation-process rule binding *who* edits libraries. mgf-livepush is a target library, and the rule governs the cross-pr |
| AG-14 | ⏳ | pyproject.toml has NO mgf-common[standards] extra (so `mgf-common doctor --standards`, the AG-14 mechanical backstop, cannot resolve the corpus); no PUBLIC_API.{md,json} exists anywhere | AG-14 ("propagate a change to its coupled surfaces in the same change; run mgf-common doctor --standards as the mechanical backstop") is the agent-facing form of DOC-18 and IS partly checkable on a published sibling: the coupled s |
| AG-15 | N/A | Standard §9: "AG-15 \| Review-only (the charter grants license, not a checkable artifact)."; the only checkable coupling is the corpus install via AG-16. | AG-15 ("agents are empowered — and MUST read the Agent Empowerment Charter — to push back / decline-with-rationale, never silently comply or skip") is explicitly review-only and, per §9, "grants license, not a checkable artifact." |
| AG-16 | ✅ | pyproject.toml:30-32 dependencies = ["mgf-common>=0.41,<0.47"] — plain, NO [standards]; pyproject.toml:40-49 dev extra lists pytest/ruff/mypy/import-linter/mgf-test-supervisor but NOT m | AG-16 ("Every project MUST keep the standards corpus resolvable to its agents — depend on mgf-common[standards]") is directly checkable on a published sibling and is the prerequisite for the loud-degrade CLI commands (standards / — FIXED 2026-06-08: separate [standards] extra (mgf-common[standards]; OUT of [dev]) |
| AG-17 | ✅ | docs/memory/MEMORY.md present at repo root | app-doctor ✓ AG-17. |
| AG-18 | ✅ | my_stuff/ git-ignored (.gitignore); .githooks/prepare-commit-msg hook present | app-doctor ✓ AG-18 (both conditions met). |
| AG-19 | N/A | ~/.claude/projects/slug/memory/ absent — no runtime auto-memory store for this project yet; nothing to track | app-doctor: no auto-memory store configured. N/A. |
| TM-01 | N/A | no datetime crosses a boundary in this repo's code. |
| TM-02 | N/A | no datetime wire format emitted. |
| TM-03 | N/A | no duration measurements with a wall clock (timeouts are not timed spans). |
| TM-04 | N/A | no `datetime.now()` in production logic. |
| 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). |
