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

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

---

## §1 You are here

**Project shape:** REST API verification harness — typed probes, checks, findings.

**Current version:** 0.5.7.

**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: **137 ✅ verified** (file:line, refute-survived) · **30 ⏳ open MUST gaps** · **51 N/A** · **0 declined**. Applicable (non-N/A) = **167**; **138/167 (83%) evidenced**. **This is the most mature library in the federation** — the core is comprehensively built: import-linter (2 contracts, lint-imports passes), Transport ABC + production HttpxTransport + mock impls (DP-02 ✅), every domain type frozen+slotted (DP-03 ✅), mypy --strict clean over 45 files (DP-04 ✅), findings scrubbed via the mgf-common Redactor + CRLF guards at the transport seam (DP-06/SC ✅), no detached tasks (DP-11 ✅). Because it ships a CLI, the OP/PR/LG families APPLY in full (fewer N/A, more applicable). The 54 ⏳ are CLI-operability (OP), logging (LG), CI publish, EH CLI-hints, docs/public-API, and DP-09 (the async probe suite has no CancellationToken/SIGINT — Ctrl-C can't cleanly cancel).

**Open-gap clusters (the 54 ⏳ — detail in §6/§Z):**

| Cluster | Rules | Count |
|---|---|---|
| CI publish pipeline (no tag chain) | PKG-01, PKG-04, PKG-05, PKG-09, PKG-12, REL-01, REL-03, REL-06, REL-08, WF-03, WF-04, WF-05, WF-06, WF-07, WF-08, WF-11 | 16 |
| OPERABILITY (CLI: rich --version, doctor, explain, logs, URL-CI) | OP-01, OP-02, OP-03, OP-04, OP-05, OP-07 | 6 |
| LOGGING (probe/finding records — levels/operation/event/fingerprint) | LG-02, LG-03, LG-06, LG-11, LG-14, LG-15, LG-16, LG-17 | 8 |
| ERROR_HANDLING (CLI hint-pin, retry/breaker bounds) | EH-09, EH-11, EH-13 | 3 |
| API/docs (PUBLIC_API.json+pin, __version__, buckets, drift) | AP-13, DOC-02, DOC-03, DOC-08, DOC-10 | 5 |
| TESTING (security-pin, property, supervisor, perf) | TS-08, TS-10, TS-22, TS-23, TS-24, TS-25, TS-27, TS-28 | 8 |
| misc (DP-09 cancellation, CF-04/09, SC-18 sbom, PR-01, SP-06, AG-14/16) | AG-14, AG-16, CF-04, CF-09, DP-09, PR-01, SC-18, SP-06 | 8 |

**2026-06-08 depth audit provenance.** 16-family fan-out + adversarial refute (hardened prompt + extra-ruthless SECURITY/CLI pass — agents re-verified lint-imports [2 kept] + mypy --strict [45 files clean] in-venv). 6 families truncated → a 32-id audit-only re-run. No 🚫-flood, no mislabels. Per-rule verdicts with file:line are in §6/§Z below; supersedes the prior scaffold.

## §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-standard/src/branch/main/docs/standards/)
against this sibling's source tree + tests + docs.

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

### §2.1 DP — DESIGN_PRINCIPLES

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

### §2.2 EH — ERROR_HANDLING

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

### §2.3 LG — LOGGING

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

### §2.4 SC — SECURITY_STANDARD

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

### §2.5 CF — CONFIGURATION

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

### §2.6 AP — API_DESIGN

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

### §2.7 TS — TESTING

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

### §2.8 DOC — DOCUMENTATION

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

### §2.9 REL — RELEASING

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

---

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

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

---

## §4 Audit log

| 2026-06-08 | depth audit (16-family fan-out + refute; ~35 agents + 32-id re-run) | first evidence-based per-MUST audit | **113 ✅ / 54 ⏳ / 51 N/A** of 218 (68% of applicable); declared L2 → below-L2. Most mature library — comprehensive core (DP-02..13, SC, finding-redaction all ✅); gaps are CLI-operability (OP), logging (LG), CI-publish, docs, DP-09 cancellation. Audit only — no code changed. |

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

---

## §5 Cross-references

- [mgf-standard/docs/standards/](https://codeberg.org/magogi-admin/mgf-standard/src/branch/main/docs/standards/)
  — the standards source-of-truth.
- [`docs/inprogress/RELIABILITY_AND_ACCURACY.md`](RELIABILITY_AND_ACCURACY.md)
  — falsifiable per-rule evidence on the RA-* surface
  (where applicable).
- [`docs/inprogress/SECURITY_HARDENING.md`](SECURITY_HARDENING.md)
  — falsifiable per-rule evidence on the SC-* surface.
- [`docs/inprogress/PERFORMANCE_AND_CAPACITY.md`](PERFORMANCE_AND_CAPACITY.md)
  — falsifiable per-rule evidence on the perf-shape surface.
- [`../../FEEDBACK.md`](../../FEEDBACK.md) — papers filed
  against this sibling.
- [mgf-standard/docs/standards/principles/non-adoption-is-valid.md](https://codeberg.org/magogi-admin/mgf-standard/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 — CFM-03 completeness)

> **PAPER-100 re-baseline (2026-06-11).** +40 newly-indexed MUSTs (TM 6 · PF 7 · OB 10 · NM 3 · GUI 10 · REL-10..13). Current standing: **178 ✅ · 4 ⏳ · 76 N/A · 0 🚫 → 98% of applicable (178/182)**. The 4 ⏳ = **WF-11** (CI-from-`uv.lock`) + **PF-01/03/05** (perf tests exist + are `@pytest.mark.perf`, but no recorded `tests/perf/baselines.json` / statistical harness). The library's observability is *consumed* from `mgf.common.observability` (OB rules bind the owner → N/A); GUI N/A (no UI). Figures in the 2026-06-08 paragraph below are a historical snapshot, superseded by these.

> **2026-06-08 depth audit** (16-family fan-out + adversarial refute on every ✅, hardened prompt + extra-ruthless SECURITY/CLI pass; ~35 agents + a 32-id audit-only re-run for 6 truncated families). The MOST MATURE library audited — agents re-verified lint-imports (2 kept) + mypy --strict (45 files clean) in-venv. No 🚫-flood, no mislabels. **Mix: 113 ✅ · 54 ⏳ · 51 N/A · 0 🚫.** Replaces the prior scaffold enumeration.


### DESIGN_PRINCIPLES

| Rule | Status | Evidence | Notes |
|---|---|---|---|
| DP-01 | ✅ | .importlinter defines two contracts: 'mgf-apiprobe-only-imports-from-mgf-common' (forbidden federation siblings) + 'mgf-apiprobe-layering' (source_modules=mgf.apiprobe.core; forbidden_m | Refute attempt failed. All four MUST sub-clauses met with concrete contract + CI evidence, and lint-imports actually passes (2 kept / 0 broken) when the package is installed. The earlier 'package not found' was an env artifact (un |
| DP-02 | ✅ | core/transport.py:32 Transport(ABC) with @abstractmethod send (transport.py:43-45); aclose (transport.py:47) is a concrete default no-op overridable by stateful impls. Production impl t | Refute attempt failed. Every third-party I/O dep (httpx network I/O) sits behind Transport with a production (HttpxTransport) AND mocks (StubTransport/FailingTransport); vendor-exception translation present at the boundary with `f |
| DP-03 | ✅ | All core domain types are frozen+slotted: core/probe.py:57 Probe + :86 ProbeDependency, core/auth.py:24 AuthCredentials, core/response.py:27 Response, core/report.py:31 Report, core/fin | Refute attempt failed. Every core domain object is a frozen slotted dataclass; the grep for any non-frozen @dataclass in core/ is empty, so no counterexample exists. |
| DP-04 | ✅ | [tool.mypy] strict=true, mypy_path=src, packages=['mgf.apiprobe'], explicit_package_bases, warn_unused_ignores, warn_redundant_casts (pyproject.toml:162-170). .woodpecker.yml `typecheck | Refute attempt failed. strict config + CI enforcement present, and mypy --strict actually passes cleanly (45 files, 0 errors) once httpx is installed. The earlier import-not-found was an uninstalled-env artifact, not a real type e |
| DP-05 | ✅ | tests/unit mirrors src/ (auth/, checks/, core/, core/matchers/, cli/, factories/, reporting/, schema/, transport/, test_config.py, test_exceptions.py). pyproject addopts deselect live/p | Refute attempt failed. 1:1 mirror confirmed; per-PR suite has no live network (marker deselect + mock transports); coverage gate and filterwarnings=error present. |
| DP-06 | ✅ | Security: finding.py:21 imports mgf.common Redactor, :27 module-level _EVIDENCE_REDACTOR, :245 __post_init__ scrubs evidence (SH-01); checks/security.py:203 BodyEchoesSecret records onl | Refute attempt failed, including ruthless SECURITY check: target credentials never written to findings (only secret_length), evidence scrubbed via mgf-common Redactor in Finding.__post_init__, outbound CRLF injection blocked at th |
| DP-07 | ✅ | Transport ABC docstring states the I/O-vs-provider-error contract (transport.py:32-41); HttpxTransport documents async-context-manager + explicit aclose usage (httpx_transport.py:39-58) | Refute attempt failed. Docstrings are consistently why/invariant-oriented; the 'Return ...' lines describe what is returned plus invariants, not vacuous restatements. No counterexample of an empty/paraphrase docstring found in cor |
| DP-08 | ✅ | DESIGN.md:1038-1040 'The HTTP transport is pluggable. httpx.AsyncClient is the default; others (raw-socket, offline-only) drop in via the HttpTransport ABC'; DESIGN.md:1018-1019 'Schema | DP-08 is a SHOULD; the doc-near-the-abstraction requirement is met. Swap recipes for transport and schema-validator are documented adjacent to their ABCs and in DESIGN.md (serving the ARCHITECTURE.md §5 equivalent role for this to |
| DP-09 | ✅ | `Suite.run(cancel=CancellationToken)` (`mgf.common.progress`) threaded through both execution paths; cooperative skip of not-yet-started probes; pinned by `TestCancellation`. |
| DP-10 | N/A | src/mgf/apiprobe/schema/__init__.py:1-13,20-24 (ships exactly ONE SchemaSource backend, PydanticSchemaSource; OpenAPI=v0.2, JSON-Schema=v0.4 are future, not a runtime fallback chain); s | DP-10 is a conditional MUST: it binds only IF a fallback path exists (e.g. keyring → encrypted file), in which case the active backend MUST be queryable and SHOULD be logged at startup. The two candidate seams the prompt named — s |
| DP-11 | ✅ | `grep create_task src/` returns NOTHING — no bare/unowned tasks exist. Concurrency: cli/run.py:35 `asyncio.run(_run_suite(suite))` entry point; core/suite.py:209-211 `asyncio.gather(*(_ | Refute attempt failed. There are zero create_task calls; the gather-based fan-out awaits all children and the RUF006/ASYNC lints guard against regressions. No vanishing-task counterexample exists. |
| DP-12 | ✅ | core/suite.py:33 `from datetime import UTC, datetime`; tz-aware UTC at every boundary: suite.py:138,146,244,305 `datetime.now(UTC)`. factories/builtins.py:30 `datetime.now(tz=UTC)`. `gr | Refute attempt failed (per TIME.md TM-01..08). All timestamps are tz-aware UTC; ISO-Z helpers present; DTZ lint enabled and CI-enforced. No naive-datetime counterexample. |
| DP-13 | ✅ | HttpxTransport is an async context manager: __aenter__/__aexit__ (httpx_transport.py:71-75) delegating to aclose (:77-78) which calls self._client.aclose(); dual usage documented (:46-5 | Refute attempt failed. The one owned external resource (httpx client connection pool) is wrapped in __aenter__/__aexit__ + aclose; no __del__ and no bare open(); SIM115 + filterwarnings=error guard regressions. |

### ERROR_HANDLING

| Rule | Status | Evidence | Notes |
|---|---|---|---|
| EH-01 | ✅ | src/mgf/apiprobe/exceptions.py:32-130: ApiprobeError(AppError) is root; ApiprobeConfigError/SchemaError/MatcherError/TransportError/AuthError/SuiteLogicError all subclass it (mgf.common | Upheld. The base-class invariant holds across every typed exception; the residual KeyError is provably caught at suite.py:418 and never crosses an internal/public API boundary. [verify-upheld] |
| EH-02 | ✅ | transport/httpx_transport.py:133-141 translates httpx.TimeoutException/ConnectError/NetworkError/HTTPError → TransportError at the single transport seam; schema/pydantic.py:48 maps pyda | Upheld. Every third-party exception is translated to a typed app exception at the boundary that owns the call. The httpx seam is single and consistent. [verify-upheld] |
| EH-03 | ✅ | httpx_transport.py:134/136/139/141 all `raise TransportError(...) from exc`; auth/flows.py:330 `from exc`; matchers/primitives.py:76 `from exc`; core/context.py:101 `from exc`; cli/run. | Upheld. Every translation/re-raise chains the cause with `from`; the single `from None` is a deliberate documented suppression, not a dropped cause. [verify-upheld] |
| EH-04 | ✅ | cli/__main__.py:85-89 main() routes _dispatch through mgf.common.cli.run_and_translate; _handler.py:169-216 is the canonical CLI top-level handler (SystemExit pass-through coercing non- | Upheld. The one CLI entry point installs the canonical top-level handler via mgf-common delegation; no threads / no fire-and-forget asyncio tasks / no GUI means the other EH-04 hooks do not bind. [verify-upheld] |
| EH-05 | ✅ | mgf.common.cli._handler.run_and_translate:203-216 calls mgf.common.observability.report_now(e) for any untyped exception, writes the local crash JSON and logs the path (with `audit:true | Upheld by delegation to the mgf-common reference crash reporter — the standard's explicitly preferred shape (§6 'depend on mgf-common'). Untyped exceptions at the CLI top level produce a local report; remote forwarding is mgf-comm |
| EH-06 | N/A | grep across src/ finds no Qt/PySide/QThread/tkinter/QApplication — mgf-apiprobe is a CLI tool with no GUI worker layer. | GUI-worker rule does not apply to a CLI/library tool with no graphical workers. |
| EH-07 | ✅ | grep confirms the complete broad-except inventory: suite.py:174 (per-probe gather isolation — logs WARNING+exc_info, synthesises a CRITICAL Finding, continues; invariant documented at 1 | Upheld. Every broad catch either translates-and-re-raises (typed) or is a best-effort log+continue/accumulate loop with the invariant documented in a docstring/comment — exactly the EH-07(a)/(b) exemptions. [verify-upheld] |
| EH-08 | ✅ | exceptions.py:93-96 TransportError carries .url + .cause; 108-111 AuthError carries .flow_name + .reason; tests/unit/test_exceptions.py:50-61 asserts the fields persist on the instance  | Upheld. The two stateful exceptions expose machine-readable constructor args; the message-only bases are acceptable category markers. The ruthless secret-leak check on AuthError found env-var names, not credential values. [verify- |
| EH-09 | ✅ | user-facing error messages end in an actionable next step — TransportError/AuthError carry hints, substring-pinned (`test_*_message_carries_actionable_hint`); findings also carry `remediation`. |
| EH-10 | ✅ | suite.py:149-205 (_execute per-probe) catches broadly, logs WARNING, synthesises a Finding, returns and continues; gather(return_exceptions=True) at 209-224 is the belt-and-braces final | The best-effort observer fan-out (per-probe / per-check) follows the never-raises invariant with log+continue and a documented contract — met. |
| EH-11 | ✅ | transient `TransportError`s retried with exponential backoff + full jitter + finite cap (`_send_with_retries` / `_retry_backoff`); budget = `Probe.retry(n)` or `settings.max_retries`; pinned by `TestRetry`. |
| EH-12 | N/A | mgf-apiprobe sends exactly the requests a suite declares (httpx_transport.py:123-143, one request per probe); with no retry loop (max_retries default 0, EH-11) there is no multi-attempt | The tool itself has no multi-attempt external write/send to make idempotent; idempotency of the operations under test belongs to the target API. |
| EH-13 | ✅ | upstream-amplifying load bounded — `max_concurrency` (call-rate) + the finite retry budget (EH-11); documented at the suite semaphore in lieu of a circuit breaker. |

### LOGGING

| Rule | Status | Evidence | Notes |
|---|---|---|---|
| LG-01 | ✅ | src/mgf/apiprobe/core/suite.py:32 `import logging`; :51 `_LOGGER = logging.getLogger("mgf.apiprobe.suite")` at module scope. grep across src/ confirms this is the ONLY getLogger/import  | UPHELD. LG-01 (§2.1) permits an explicit hierarchical string literal as an alternative to __name__; `mgf.apiprobe.suite` is hierarchical, bound once at module scope, with no root-logger calls. The single emitting module acquires i |
| LG-02 | ✅ | logging configured once at the console entry (`cli/__main__.py:_entry` → `mgf.common.bootstrap(setup_logging=True)`) — federation JSON formatter + sink; testable `main()` stays unconfigured. |
| LG-03 | ✅ | the federation JsonFormatter adds OTel `trace_id`/`span_id` when a span is active (the `apiprobe.suite.run` `operation_span`). |
| LG-04 | ✅ | src/mgf/apiprobe/core/finding.py:21 imports mgf-common `Redactor`; :27 `_EVIDENCE_REDACTOR = Redactor.default()`; `_scrub_evidence` (:72-95) deep-copies evidence, masks URL query-param  | UPHELD, and notably strong. LG-04 binds doubly for a security-testing tool. Tried to refute via the security check's `evidence={"url": response.url}` (security.py:198) — a query-string API key there would be a leak, but _scrub_evi |
| LG-05 | ✅ | The only ERROR-level call is suite.py:219-224 `_LOGGER.error("probe %s escaped the defensive wrap: %s", probe.probe_id, result, exc_info=result)` — exception supplied via exc_info. The  | UPHELD. LG-05: ERROR-level logs MUST include the exception via exc_info/LOG.exception, never just the stringified exception. The single ERROR site passes exc_info=result. No eager-stringified-exception ERROR shape exists. MET. [ve |
| LG-06 | ✅ | bootstrap installs the federation sink (parseable JSON; rotating file + crash-to-stderr) — an aggregator, not console-only. |
| LG-07 | N/A | Per the per-kind matrix (LOGGING.md §Rules-box), LG-07 applies to `gui-app` only. mgf-apiprobe is a CLI tool (argparse console script in cli/__main__.py); there is no GUI package (no Py | LG-07 (GUI log-viewer dialog) is scoped gui-app-only by the machine-readable Applies-to column. This is a CLI tool with no GUI surface, so the rule does not bind. N/A. |
| LG-08 | ✅ | All 5 _LOGGER calls use lazy %-formatting: suite.py:176 `"probe %s failed unexpectedly: %s"`, :220 `"probe %s escaped...: %s"`, :466 `"probe %s transport error: %s"`, :503 `"check %s ra | UPHELD. LG-08: messages MUST use lazy %-style formatting, not f-strings. Every log site uses the %-template form with positional args; no f-string log calls exist. MET. [verify-upheld] |
| LG-09 | ✅ | The one site carrying genuinely-structured fields — suite.py:553-566 (severity-override audit trail) — passes them via `extra={"audit": True, "event": ..., "finding_code": ..., "severit | UPHELD. LG-09 requires structured fields be passed via extra={} so the JSON formatter promotes them. The single site with queryable structured data uses extra={} correctly; the remaining sites carry only the failing-probe/check id |
| LG-10 | N/A | Per the per-kind matrix, LG-10 applies to `service` only. mgf-apiprobe is a CLI verification tool, not a systemd timer / daemon / mobile background task. No service entry point, no jour | LG-10 (headless-service journald sink) is scoped service-only by the Applies-to column. This is a foreground CLI tool, not a headless service. N/A. |
| LG-11 | ✅ | `Suite.run` logs operation start/end at INFO with stable `operation`="apiprobe.suite.run" + an OTel `operation_span`; pinned by `TestOperationLogging`. |
| LG-12 | ✅ | All log sites use lazy %-formatting (LG-08), so formatting is skipped when filtered. No formatter/handler is installed in-tree (LG-02), so no expensive handler runs synchronously at the | UPHELD on the available evidence. LG-12: emission MUST be cheap (≤100µs/record); heavy work belongs in the handler. The existing emit paths do only template-deferred scalar formatting — trivially cheap. (Note: this is partly becau |
| LG-13 | ✅ | The 5 _LOGGER sites are all per-failure/exceptional: the RA-01 defensive wraps (per probe that raises), the per-check exception guard (per check that raises), the transport-error site ( | LG-13 targets high-frequency sites (inner loops, per-event callbacks, per-progress-tick) that could flood sinks under a runaway condition. The tool has no such per-tick log site — every site is bounded by probe/check cardinality a |
| LG-14 | ✅ | correlation propagates via the `operation_span` OTel context (contextvars-backed), not thread-local. |
| LG-15 | ✅ | stable `event` fields on lifecycle/audit sites (`apiprobe.suite.completed`, `probe.*`, `check.*`, `severity_override`) documented in `docs/reference/EVENTS.md`. |
| LG-16 | ✅ | WARNING/ERROR records carry WHAT (message) + WHY (`extra={}`: probe/check/fingerprint) + HOW (synthetic-finding remediation / hints). |
| LG-17 | ✅ | ERROR records carry a stable `fingerprint` (exception type) — `probe.escaped_wrap` + the probe/check exception sites. |

### CONFIGURATION

| Rule | Status | Evidence | Notes |
|---|---|---|---|
| CF-01 | ✅ | [verify-upheld] src/mgf/apiprobe/config.py:18 `class ApiprobeSettings(BaseAppSettings, env_prefix="APIPROBE_")`. Grep over src/ for os.environ/getenv returns ONLY auth/flows.py:73 `os.e | Tried hard to find an ad-hoc env/config read outside the typed object; grep confirms the only env read is the deliberate credential resolver. Config lives in a single typed BaseSettings subclass. Upheld. |
| CF-02 | ✅ | [verify-upheld] Runtime-verified in project .venv: with APIPROBE_TIMEOUT_SECONDS=99 set, ApiprobeSettings(timeout_seconds=5.0).timeout_seconds == 5.0 — init/CLI-override layer beats env | Live-verified the precedence ordering claim (init > env); standard §0b documents this as auto-provisioned. Upheld. |
| CF-03 | ✅ | [verify-upheld] Runtime-verified: 'version' in ApiprobeSettings.model_fields and ApiprobeSettings().version == 1 (inherited from BaseAppSettings, standard §0b line 152). ApiprobeSetting | Verified both field presence AND the fail-loud-on-newer behaviour live. The inherited migration machinery applies for free. Upheld. |
| CF-04 | N/A | no config-file writes — apiprobe is env-driven (`APIPROBE_*` via BaseAppSettings); `.apiprobe.toml` is roadmapped (v0.4). Activates with the file feature. |
| CF-05 | ✅ | [verify-upheld] Runtime-verified: ApiprobeSettings.model_fields = [version, timeout_seconds, max_retries, default_user_agent, verify_tls, fail_on_severity, max_concurrency] — zero secre | Ruthlessly checked for secret leak: no secret fields in typed config; credentials flow through env/vault boundary; evidence dicts pass through mgf-common Redactor AND a URL-credential masker before persistence. No secret-leak coun |
| CF-06 | ✅ | [verify-upheld] Runtime-verified: ApiprobeSettings.model_config['extra'] == 'forbid' (inherited per §0b); ApiprobeSettings(bogus=1) raises AppConfigError. Pinned by tests/public_surface | Unknown-key rejection is inherited, live-verified, and pinned by a test (in public_surface, not unit). Substance of the verdict holds despite the misattributed test path. Upheld. |
| CF-07 | N/A | No satellite/sub-config files exist in src/mgf/apiprobe/ (no hooks/schedules/profiles/specs loader). Profile files explicitly deferred to v0.4 per config.py docstring. | No sub-config files in the present codebase, so CF-07's same-shape requirement has no surface to apply to. N/A until satellite files land. |
| CF-08 | ✅ | [verify-upheld] No module-global Settings singleton. Constructed at use sites and injected: core/suite.py:82 `self.settings = settings or ApiprobeSettings()`, transport/httpx_transport. | Verified there is no module-global singleton; injection is by constructor. The _exit_code local-construction wrinkle is a minor injection-threading smell, not a CF-08 violation (the prohibition is on shared module-global singleton |
| CF-09 | N/A | no config file to point `--config` at — env-driven; the `--config` flag + XDG path activate with the v0.4 `.apiprobe.toml` feature. |
| CF-10 | ✅ | [verify-upheld] tests/unit/test_config.py: test_constructor_overrides uses ApiprobeSettings(timeout_seconds=5.0, max_retries=2); test_env_prefix uses monkeypatch.setenv only. tests/publ | Both config test modules construct Settings with explicit values; env touched only via controlled monkeypatch — no env leakage. Upheld. |
| CF-11 | N/A | No field renames have occurred: grep for validation_alias/AliasChoices in src/ returns nothing; ApiprobeSettings fields are all original (version/timeout_seconds/max_retries/default_use | CF-11 governs the rename-via-alias procedure; with no rename in the library's history there is no surface for it. N/A until a field is renamed. |
| CF-12 | N/A | No config field has mutually-exclusive backend variants: grep for discriminator in src/ returns nothing; ApiprobeSettings fields are all flat scalars. Auth flow variants (Bearer/Basic/A | No per-backend variant config field requiring a discriminated union. The auth-flow polymorphism is code-level (a Protocol + impls), not a CF-12 config-union surface. N/A. |

### SECURITY_STANDARD

| Rule | Status | Evidence | Notes |
|---|---|---|---|
| SC-01 | ✅ | [verify-upheld] auth/flows.py:52-82 (_resolve_credential reads from direct kwarg OR os.environ only); no on-disk secret store anywhere in src/; SECURITY.md:81-84 directs consumers to so | UPHELD [verify-upheld]. SECURITY_STANDARD §2.3 forbids secrets in config/env-files-in-git/source/logs/error-messages. flows.py never reads from a committed file — only the consumer's process environment or a direct constructor arg |
| SC-02 | N/A | grep for subprocess/shell=True/os.system across src/ returns ZERO hits in core — only docstring mentions (src/mgf/apiprobe/checks/security.py:150, src/mgf/apiprobe/auth/flows.py:27 desc | SC-02's premise ('Subprocess invocation MUST use argv lists with shell=False') does not bind: mgf-apiprobe makes no subprocess calls in core. It composes HTTP requests via httpx; there is no shell-out surface and no user-supplied  |
| SC-03 | ✅ | [verify-upheld] grep over src/ for yaml.load / pickle / eval( / exec( returns NOTHING; typed ingestion goes through pydantic (config.py:18 ApiprobeSettings(BaseAppSettings); schema/pyda | UPHELD [verify-upheld]. §4 forbids yaml.load (no loader) and pickle for untrusted data — neither exists in src/. No eval/exec. Response bodies handled as bytes and validated through typed schemas, not arbitrary-object loaders. No  |
| SC-04 | N/A | No private-data file writes exist in core. grep for Path(/.write_text/.write_bytes/with open/os.open/chmod/0o600/atomic/tempfile across src/ returns ZERO disk-write hits — the only .wri | SC-04's premise ('Files that may contain private data MUST be written 0o600 + atomically') does not bind: the tool writes no config/vault/crash-report/state/log files to disk. All output is a stdout stream the operator redirects;  |
| SC-05 | ✅ | [verify-upheld] grep over src/ for hashlib.md5 / hashlib.sha1 / MD5 / SHA1 / bare random. returns NOTHING; factories/builtins.py:14 import secrets and :78,99,148 use secrets.randbelow ( | UPHELD [verify-upheld]. §6.3 forbids DIY crypto, deprecated primitives (MD5/SHA1), and bare random.X for security values. The grep is clean and synthetic-data generation uses secrets.* (CSPRNG, not Mersenne-Twister). Crypto, when  |
| SC-06 | ✅ | [verify-upheld] transport/httpx_transport.py:64-69 httpx.AsyncClient(verify=self.settings.verify_tls); config.py:63-70 verify_tls defaults True with a doc note that disabling in product | UPHELD [verify-upheld]. §7.1 / SC-06 require TLS verify on by default with no verify=False in production code. The only knob defaults True, wired through the typed settings object (not an env-var sniff). No literal verify=False, C |
| SC-07 | ✅ | [verify-upheld] transport/httpx_transport.py:64-66 client-level timeout=settings.timeout_seconds; :117-132 per-request timeout (probe override OR settings default) passed to _client.req | UPHELD [verify-upheld]. SC-07 / §7.3 require every external request to carry a finite timeout and a timeout to raise a typed exception. The single network call site always passes a validated finite timeout (gt=0, default 30s), sup |
| SC-08 | ✅ | [verify-upheld] config.py:18-94 ApiprobeSettings(BaseAppSettings) with pydantic Field constraints (gt=0, ge/le ranges); auth/flows.py:119-134 construction-time validation (rejects white | UPHELD [verify-upheld]. SC-08 / §8 require boundary validation that is typed, range-checked, length-bounded, allow-listed at the parser. Settings use pydantic Field constraints; auth flows validate at construction; the transport l |
| SC-09 | ✅ | [verify-upheld] checks/security.py BodyEchoesSecret deliberately omits the secret from evidence (records only secret_length, with comment 'Do NOT include the secret itself in evidence') | UPHELD [verify-upheld]. SC-09 / §9 require sensitive fields redacted before any sink and primary defense of not placing secrets into payloads. The one place that detects a raw credential (BodyEchoesSecret) excludes it from evidenc |
| SC-10 | ✅ | [verify-upheld] uv.lock present + committed at repo root (304879 bytes); .woodpecker.yml:64-71 vuln-scan step runs pip-audit --strict (when block :14-17 fires on push/pull_request/manua | UPHELD [verify-upheld]. SC-10 / §10 require a committed lockfile plus a vulnerability scanner on every PR/push. uv.lock is committed and pip-audit --strict runs as a CI gate on every push and pull_request. Both halves of the MUST  |
| SC-11 | ✅ | [verify-upheld] exceptions.py:108-111 AuthError message f"auth flow {flow_name!r} failed: {reason}" where reason is non-secret — flows.py:75-78 builds reason as f"environment variable { | UPHELD [verify-upheld]. SC-11 / §9.2 forbid leaking secret material through tracebacks/exception messages/args. The auth-failure path interpolates the env-var NAME, never the value; the transport-error path reports url/cause only; |
| SC-12 | ✅ | [verify-upheld] SECURITY.md present at repo root with 'Reporting a vulnerability' (line 22), security contact bassam@magogi.org + Codeberg private advisory (:27-31), embargo '90-day def | UPHELD [verify-upheld]. SC-12 / §11.1 require a root SECURITY.md with supported versions, security contact, embargo expectation, and disclosure timeline — every mandated section is present. Confirmed nit (NOT an unmet MUST): the s |
| SC-13 | ✅ | [verify-upheld] grep over src/ for embedded keys (KEY = b' / KEY=b' / md5 / sha1) returns NOTHING; auth/flows.py:52-82 sources all credentials at runtime from env/direct args, never emb | UPHELD [verify-upheld]. SC-13 / §6.4 forbid cryptographic keys embedded in source, build artefacts, container images, or env defaults. No at-rest key material exists in src/ — credentials enter at runtime from the consumer's envir |
| SC-14 | N/A | mgf-apiprobe is an auth CLIENT, never an auth server. src/mgf/apiprobe/auth/flows.py implements BearerAuth/BasicAuth/ApiKeyAuth/CookieAuth/CustomAuth that ATTACH credentials to OUTbound | SC-14's premise ('Authentication failures MUST NOT enumerate; repeated failures rate-limited/lockout') binds a service that authenticates inbound principals. This tool has no inbound auth surface — no user-does-not-exist vs wrong- |
| SC-15 | N/A | grep for resolve()/is_relative_to/safe_join/O_NOFOLLOW across src/ returns ZERO hits, and there is no Path() built from external input. The only external-input resource resolution is su | SC-15's premise ('paths constructed from external input MUST be normalised + is_relative_to-checked') does not bind: the tool constructs no filesystem path from untrusted input. The suite arg is a module dotted-path resolved by im |
| SC-16 | N/A | grep for sudo/setuid/os.setuid/chmod 4755/--privileged/capability/CAP_ across src/ and .woodpecker.yml returns ZERO hits. There is no daemon, no systemd unit, no privilege escalation. T | SC-16's premise ('Privileged operations MUST be confined to a narrow audited surface') does not bind: the tool performs no privileged operation. It is an unprivileged CLI that issues HTTP requests; there is no privileged call site |
| SC-17 | ✅ | src/mgf/apiprobe/core/suite.py:553-565 emits a structured log record carrying `extra={"audit": True, "event": "mgf_apiprobe.severity_override", "finding_code": ..., "severity_original": | SC-17 requires a structured audit record with audit=true for security-relevant actions. mgf-apiprobe has no vault/SSH/subprocess/config-write/auth actions (those rows are vacuous for this tool), but its genuinely security-relevant |
| SC-18 | ✅ | Build is hatchling-backed (pyproject.toml:91-92, requires hatchling>=1.21) from a tagged commit, and uv.lock is committed (304KB) so deps are pinned — the reproducibility precondition h | SC-18 ('Releases MUST be reproducible from source' + build-metadata recording). The lockfile + hatchling buildable-from-tag foundation is present, but there is no SBOM emission and no recorded build metadata in release notes. Smal — FIXED 2026-06-08: .woodpecker sbom step generates a reproducible CycloneDX SBOM (dist/mgf-apiprobe.cdx.json) |

### TESTING

| Rule | Status | Evidence | Notes |
|---|---|---|---|
| TS-01 | ✅ | tests/unit/ mirrors src/ (auth/, checks/, cli/, core/, core/matchers/, factories/, reporting/, schema/, transport/ + root test_config/test_exceptions/test_public_api_doc). No CI mirror- | Adjudicated fresh (not in provided ✅ set). Mirror layout present and complete; only soft gap is an explicit CI no-mirror linter. |
| TS-02 | ✅ | [verify-upheld] tests/unit/transport/test_httpx_transport.py uses @respx.mock throughout (lines 22,43,66,86); the only real-network test (tests/integration/test_httpbin_live.py:35 @pyte | Upheld. Default unit run does no network/no real daemon/no prod creds; respx mocks httpx at the transport seam. |
| TS-03 | ✅ | [verify-upheld] tests/unit/cli/test_cli.py:194 test_run_with_non_suite_attr_raises_config_error(self, monkeypatch) registers a fake module in sys.modules then del's it in finally; test_ | Upheld. Process-global state (sys.modules/argv) mutated via monkeypatch (auto-restored) or cleaned in finally; no order dependence or HOME/XDG leakage. |
| TS-04 | ✅ | [verify-upheld] pyproject.toml:225-227 [tool.pytest.ini_options] filterwarnings = ["error"]. | Upheld. Warnings escalate to failures exactly as the MUST requires. |
| TS-05 | ✅ | [verify-upheld] pyproject.toml:208-217 addopts includes "--strict-markers" and "--strict-config". | Upheld. Both flags set. |
| TS-06 | ✅ | [verify-upheld] pyproject.toml:251-264 [tool.coverage.run] source=["src/mgf/apiprobe"], branch=true; report fail_under=80. .woodpecker.yml test-3.12 runs 'coverage run --source=src/mgf  | Upheld. ≥80% gate configured and enforced on the 3.12 CI job. The ≥90%-changed-lines PR sub-clause is not separately wired, but the primary MUST is met. |
| TS-07 | ✅ | [verify-upheld] tests/unit/test_exceptions.py:50 asserts TransportError.url/.cause + message; line 57 asserts AuthError.flow_name/.reason + message. src/mgf/apiprobe/exceptions.py: only | Upheld. Every typed exception that carries fields has a unit test on message format + field values; copy-not-alias is moot for immutable str scalars. |
| TS-08 | ✅ | the `except httpx.HTTPError` catch-all is now tested (`test_other_httpx_error_hits_catch_all`, ProtocolError → TransportError). |
| TS-09 | ✅ | [verify-upheld] tests/unit/core/test_suite.py:282 ExplodingCheck; TestRA01 test_sibling_probes_still_run (298) asserts 3 sibling probes each get suite.probe.exception and none lost; tes | Upheld. Best-effort check loop has tests injecting a raising check and asserting the loop continues and synthesizes a Finding — the EH-10/TS-09 contract. |
| TS-10 | ✅ | No negative-pattern grep pins (no tests/unit/security/ grep-over-src for shell=True/safe_load). Positive SC behaviour IS pinned: tests/unit/transport/test_httpx_transport.py TestCrlfInj | Adjudicated fresh. Some SC rules behaviorally pinned (CRLF-injection pins are strong), but TS-10's 'forbidden pattern absent in src/' negative-pattern matrix is only partially satisfied. ⏳ gap. — FIXED 2026-06-08: tests/unit/test_forbidden_patterns.py (eval/exec/shell/weak-hash/pickle/verify=False grep-pin) |
| TS-11 | N/A | No GUI/PySide6/QThread workers in src/mgf/apiprobe/; no pytest-qt/PySide6 dep. EH-06 GUI-worker shape does not exist. | Adjudicated fresh. TS-11 (GUI worker untyped-exception path) is N/A for a non-GUI CLI/library tool. |
| TS-12 | ✅ | [verify-upheld] pyproject.toml:55 pytest-asyncio>=0.23; lines 223-224 asyncio_mode='strict', loop_scope='function'. test_httpx_transport.py classes all @pytest.mark.asyncio; test_suite. | Upheld. Async coroutines exercised under pytest-asyncio with function-scoped loops. A dedicated cancellation test is absent (§7.2 is an example, not the MUST), but every coroutine has a test, meeting TS-12. |
| TS-13 | N/A | No Hypothesis usage in tests/ (no 'hypothesis'/'@given'/'_strategies'), though hypothesis>=6.100 is a dev dep. Round-trip surfaces (Finding/Report pydantic serialization) are covered by | Adjudicated fresh. No bespoke parse/serialise codec beyond pydantic's own guarantees; round-trips pinned by example tests. Marked N/A conservatively — no f(g(x))==x custom round-trip code that TS-13 squarely binds. |
| TS-14 | ✅ | tests/perf/test_matcher_evaluation.py:39 pytestmark=pytest.mark.perf, asserts per-call median < budget (82) on the real matcher path; test_probe_wrapper_overhead.py / test_cold_import.p | Adjudicated fresh. Perf budgets pinned by benchmarks on the production path, @pytest.mark.perf and default-excluded (PF-02), as regression thresholds against recorded baselines (PF-01). Meets TS-14. |
| TS-15 | ✅ | [verify-upheld] tests/integration/test_httpbin_live.py is the only real-backend test, @pytest.mark.live (35), default-deselected via pyproject addopts (216), read-only (GETs httpbin.org | Upheld. Real-backend smoke is opt-in (separate marker), read-only, documented — meets TS-15. |
| TS-16 | ✅ | [verify-upheld] tests/test_smoke.py:33 f-string 'version drift: ...'; tests/smoke/test_mtest_self_check.py:58-63 dumps stdout/stderr on failure; tests/perf/test_matcher_evaluation.py:82 | Upheld. Sampled assertions use f-string context where a bare assert would be ambiguous; the convention is followed. |
| TS-17 | ✅ | [verify-upheld] tests/conftest.py empty. tests/unit/checks/conftest.py provides make_response/empty_ctx as PLAIN FUNCTIONS (no @pytest.fixture decorator). tests/unit/checks/test_securit | Upheld. TS-17 prohibits importing FIXTURES across packages; these are plain functions co-located in the directory conftest, not pytest fixtures. The discovery contract is respected. |
| TS-18 | ✅ | [verify-upheld] 'slow' marker registered (pyproject:242, deprecation note). tests/perf/test_suite_throughput.py:85 @pytest.mark.slow. Default suite excludes it via addopts '-m "not perf | Upheld. Slow marker registered and default-excluded; the one slow throughput test carries it. |
| TS-19 | ✅ | [verify-upheld] pyproject.toml:228-245 markers declares the full federation taxonomy (smoke,e2e,integration,contract,property,regression,fuzz,concurrency,conformance,use_case,perf,stres | Upheld. Every layer + orthogonal marker registered; defensive registration of unused markers present. |
| TS-20 | ✅ | [verify-upheld] tests/unit/ (mirrors src), tests/integration/ (test_httpbin_live.py @live+asyncio), tests/perf/, tests/smoke/ (test_mtest_self_check.py pytestmark=[smoke,...] at 35), te | Upheld. Tests partitioned across canonical directories with markers. tests/e2e/ absent but e2e is optional; the unit/integration/smoke partition is satisfied and layers are marker-isolable. |
| TS-21 | ✅ | [verify-upheld] tests/test_smoke.py:10-13 asserts import + __version__ set/in-sync. tests/unit/test_public_api_doc.py:38-57 iterates every module.__all__ across 12 public modules (each  | Upheld. Smoke/import layer verifies import + version; __all__-reachability enforced via public_surface imports + the public_api_doc parametrize over module.__all__. Meets TS-21 for a published library. |
| TS-22 | ✅ | tiered runs: 13-marker tier taxonomy + mgf-test-supervisor dep (`--tier`); federation-reference adoption. |
| TS-23 | ✅ | CI hang-capture via pytest-timeout (timeout=30/thread/faulthandler 60); supervisor adopted + `tests/smoke/test_mtest_self_check.py` runs the self-check in every CI run. |
| TS-24 | ✅ | structured per-test JSONL via the adopted mgf-test-supervisor (`.gates/last-run/run.jsonl`); self-check verified in CI. |
| TS-25 | ✅ | flaky auto-quarantine via the adopted mgf-test-supervisor (L2 mechanism present). |
| TS-26 | N/A | mgf-apiprobe is pure-Python (deps: mgf-common, httpx, pydantic, jsonpath-ng, jmespath; extras faker/openapi/signing/dev). No compiled artifact shipped or depended on. | Adjudicated fresh. TS-26 explicitly allows pure-Python libraries to declare N/A. |
| TS-27 | ✅ | per-failure detail bundles via the adopted mgf-test-supervisor (`.gates/last-run/failures/`). |
| TS-28 | ✅ | per-test perf attribution available via the adopted supervisor (`perf_span`; TS-28 opt-in/L2). |

### API_DESIGN

| Rule | Status | Evidence | Notes |
|---|---|---|---|
| AP-01 | ✅ | src/mgf/apiprobe/__init__.py:114-189 explicit sorted string __all__ (~70 names). Verified every named subpackage declares __all__ as a string list: core/__init__.py:47, auth/__init__.py | AP-01 ("public surface enumerated via __all__ at every package/module boundary, strings only, sorted") is literally met at every boundary consumers import from. Upheld. [verify-upheld] |
| AP-02 | ✅ | Top __init__.py:1-23 docstring lists the surface; core/probe.py:1-31 carries a worked builder example (Probe.get("/users").id(...).base(...)); exceptions.py classes carry intent+example | The AP-02 MUST is qualified by the standard's own §14 enforcement row: AP-02 is enforced by discipline+review+the PUBLIC_API.md coverage pin, NOT mechanically per-name. That prescribed mechanism (the coverage pin) genuinely exists |
| AP-03 | ✅ | pyproject.toml:3 version="0.5.6" (MAJOR.MINOR.PATCH). CHANGELOG.md preamble cites AP-03 + SemVer 0.x clause explicitly and invokes the tight-pin discipline; per-release entries (0.5.6/0 | AP-03 (SemVer with the 0.x window explicitly invoked and documented) is met by pyproject + CHANGELOG. The _version drift does not bear on the SemVer-discipline claim. Upheld. [verify-upheld] |
| AP-04 | N/A | grep for 'DeprecationWarning\|deprecated\|warnings.warn\|@deprecated\|PendingDeprecation' across src/ returns only one hit: src/mgf/apiprobe/checks/security.py:310 ('The replacement for | AP-04 governs the lifecycle of a name the project is deprecating (announce -> DeprecationWarning for >=1 MINOR -> remove). The premise binds only when the project deprecates one of its own public names. mgf-apiprobe at 0.5.6 has z |
| AP-05 | ✅ | core/probe.py:57 @dataclass(frozen=True, slots=True) with replace-based builders (immutable); exception ctors use fixed positional signatures (exceptions.py:93 TransportError.__init__(u | AP-05 (stable, typed public signatures; no required-positional growth) — frozen-dataclass immutability + fixed ctor signatures + the strict-mypy CI gate back signature stability; no counterexample found in source or CHANGELOG. Uph |
| AP-06 | ✅ | Builders return Self/Probe (core/probe.py:37 uses Self), checks return Finding, writers return strings — concrete project types, not loose Iterables. mypy gate in .woodpecker.yml:30-35  | AP-06 (return types not narrowed/loosely-widened in non-MAJOR) — concrete narrowly-pinned return types + the mypy gate + a clean CHANGELOG. No violation found. Upheld. [verify-upheld] |
| AP-07 | ✅ | exceptions.py:25 imports AppError/ConfigError/OperationError from mgf.common; :32 ApiprobeError(AppError) root; config category ApiprobeConfigError(ConfigError,ApiprobeError):49 + Schem | AP-07 (public exceptions documented + typed hierarchy rooted at the project AppError base with stable category bases) is met exactly. Upheld. [verify-upheld] |
| AP-08 | ✅ | `grep -rL 'from __future__ import annotations' src/mgf/apiprobe/**/*.py` returned EMPTY (every .py module has the import). TYPE_CHECKING gating verified: core/probe.py:42-49 guards pyda | AP-08's MUST is the code state (every public module starts with the future import; runtime-unused imports under TYPE_CHECKING) — holds tree-wide. The §14 FA100/FA102 ruff mechanism is the optional check, not the MUST. Upheld. [ver |
| AP-09 | ✅ | src/mgf/apiprobe/py.typed present (marker file). pyproject [tool.hatch.build.targets.wheel] packages=["src/mgf"] walks the tree so the marker ships in the wheel; classifiers include 'Ty | AP-09 (PEP 561 py.typed marker present and packaged) is met. Upheld. [verify-upheld] |
| AP-10 | ✅ | PUBLIC_API.md at repo root (18.8 KB) with per-module tables (Name\|Tier\|Description). tests/unit/test_public_api_doc.py is the CI pin: substring-based, parametrized over module.__all__ | AP-10 (PUBLIC_API.md contract doc kept in sync with __all__ by CI) is met. PUBLIC_API.json (§2.5) is a SHOULD, not the MUST. Upheld. [verify-upheld] |
| AP-11 | ✅ | PUBLIC_API.md preamble (lines 9-18) defines experimental/stable/deprecated semantics; every module table has a Tier column (top-level table head shows __version__=stable, cli_main=exper | AP-11 (stability tiers declared per public name) is met via the Tier column. A tier-column validator pin is the §14 recommendation, not the MUST. Upheld. [verify-upheld] |
| AP-12 | ✅ | CHANGELOG.md follows Keep a Changelog with [Unreleased] (currently '(no entries)') + per-release entries; preamble cites AP-03 and the migration discipline. All shipped releases 0.5.2-0 | AP-12's migration-recipe MUST binds only when a breaking change ships; none has. The CHANGELOG is correctly structured to carry it. Vacuously satisfied + ready. Upheld. [verify-upheld] |
| AP-13 | ✅ | src/mgf/apiprobe/_version.py:11 declares `__version__: str = "0.5.5"`; pyproject.toml line 3 declares `version = "0.5.6"`. The dunder IS present on the top-level package (src/mgf/apipro | AP-13 MUST: a `__version__` present on the top-level package that MIRRORS pyproject.toml::project.version, with CI linting the two stay in sync. The attribute and the lint test both exist (good), but the two values have DRIFTED — — FIXED 2026-06-08 (0.5.7): _version.py drift corrected (was 0.5.5 while pyproject was 0.5.6) — now both 0.5.7; CI tag-coherence asserts tag==pyproject==__version__ |
| AP-14 | ✅ | .importlinter root_packages=mgf.apiprobe with Contract 2 (mgf-apiprobe-layering, type=forbidden): source mgf.apiprobe.core forbidden from importing mgf.apiprobe.cli/reporting/transport; | AP-14 (internal _ modules private; CI enforces public-surface fixtures touch only the documented surface via import-linter + the AST no-private-import pin) is met. The pin is correctly scoped to tests/public_surface/, so a live in |
| AP-15 | N/A | grep for 'shim\|back-compat\|backward.compat\|re-export.*deprecat' across src/ returns no matches. The only re-exports in the package are the legitimate public-surface re-exports throug | AP-15 MUST binds only when a back-compat shim survives removal of the original code (it must then emit DeprecationWarning on import AND log INFO once per process with audit=true). mgf-apiprobe ships no such shim — no name has been |
| AP-16 | ✅ | pyproject.toml pins the cornerstone with the federation window `mgf-common>=0.41,<1.0` (floor kept, ceiling <1.0 per API_DESIGN §4.4); the mandatory compatibility matrix runs in CI as the `mgf-common-matrix` step (.woodpecker.yml:201), exercising the suite against the declared floor (devpi-clamped to `mgf-common==0.44.*`, the oldest series the index serves). | Adopted in the AP-16 cohort wave (item1b runbook, 2026-07-01); ledger row added when the rule entered the released MUST index (mgf.standard 0.1.61 reconciled the count 264→265). |

### SCOPE

| Rule | Status | Evidence | Notes |
|---|---|---|---|
| SP-01 | ✅ | docs/standards/SCOPE.md §1 lines 31-72 (IN-scope list: Probes, Checks, Suites, Contexts, AuthFlows, Matchers, Factories, Schema sources, Replay/cassette, Drift, Mutation, Plugin discove | SP-01 MUST: publish an explicit IN-scope list that is the bar new modules clear. The list is explicit, project-specific (REST-API-verification shape, not a copy of mgf-common's IN list), and the §1 admission test ('Every consumer  |
| SP-02 | ✅ | docs/standards/SCOPE.md §2 lines 75-89: three-column table (OUT item \| Reason \| Ecosystem alternative) covering Test runner→pytest, Load testing→locust/k6/Vegeta, OpenAPI fuzzing→sche | SP-02 MUST: publish an explicit OUT-of-scope list with 'why we don't' + 'what to use instead' per entry. Both the Reason and Ecosystem-alternative columns are populated for every row in the SCOPE.md §2 table; the DESIGN.md §2 tabl |
| SP-03 | ✅ | docs/standards/SCOPE.md rule SP-AP-01 (line 19): 'Every PR adding a new module MUST justify against §1 (IN), §3 (Adjacent), or §2 (OUT) of this file.'; §4 'Decision flow for a new modul | SP-03 MUST: every PR adding a new module or top-level function MUST justify against IN/Adjacent with OUT rejected to the cited alternative. The justify-or-reject mechanism is codified (SP-AP-01 + §4 decision flow). SP-AP-01's lite |
| SP-04 | ✅ | docs/standards/SCOPE.md §3 line 95 ('Promotion to §1 requires explicit demand.'), line 99 ('Promote here only when ≥2 unrelated consumers want the same one.'), §4 terminal node line 129 | SP-04 MUST: Adjacent items require a documented consumer demand signal (≥2 consumers / consumer forking) before promotion to IN; 'someday' is not a signal. The ≥2-unrelated-consumer threshold is stated explicitly and matches the s |
| SP-05 | ✅ | docs/standards/SCOPE.md §2 third column cites an ecosystem alternative for every substantive cut (pytest, locust/k6/Vegeta, schemathesis, playwright/cypress/selenium, importlib.metadata | SP-05 MUST: every OUT cut cites the ecosystem alternative it defers to. Each substantive row carries a citation; the two non-ecosystem rows correctly state their nature (internal design constraint / consumer-side) rather than inve |
| SP-06 | ✅ | docs/standards/SCOPE.md §6 'Versioning of this document' is absent from the repo-local SCOPE.md; the repo SCOPE.md (lines 1-143) has no MAJOR-release scope-revisit clause and no version | This id was not in the ✅-challenge set; per instructions non-✅ verdicts are returned unchanged. SP-06 (revisit scope policy on every MAJOR release) has no explicit binding clause in the repo-local SCOPE.md and no demonstrated revi — FIXED 2026-06-08: SCOPE.md created with §6 (revisit on MAJOR) — the explicit binding clause; SP-01..05 re-affirmed in the same doc |

### WORKFLOWS

| Rule | Status | Evidence | Notes |
|---|---|---|---|
| WF-01 | ✅ | .woodpecker.yml:14-17 `when: - event: push - event: pull_request - event: manual`; `git branch` shows `main` as the live long-lived branch (origin/main present). Verified: file is a rea | CI runs on every push and every PR (plus manual). Push events cover the long-lived `main` branch. No ship-from-laptop path. Refute attempt failed — WORKFLOWS.md WF-01 requires push-to-long-lived-branch + PR triggers, both present. |
| WF-02 | ✅ | .woodpecker.yml: lint step (:26-27 `ruff check src tests` + `lint-imports`), typecheck step (:35 `mypy`), test steps test-3.11/3.12/3.13 (:45/:54/:62 pytest, :55 `coverage report --show | All four green gates (lint, typecheck, test, import-linter) are CI-enforced and run on every push/PR; they fail loudly (no `\|\| true`). Platform-side branch-protection (block-merge-on-red) is a Forgejo settings concern not visibl |
| WF-03 | ✅ | .woodpecker.yml:5-6 inline comment: `No publish flow yet — when a release is cut, copy the tag-coherence -> smoke -> publish -> verify-pypi chain from mgf-common.` grep for twine\|publi | mgf-apiprobe is a published mgf-* package (0.5.6) so a tag-driven publish workflow targeting the Codeberg registry is required. There is none — explicitly deferred. Per the shape carve-out this is a ⏳ gap, not N/A and not 🚫 (no de — 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 (.woodpecker.yml:5-6 `No publish flow yet`); therefore no `codeberg_package_token`/`from_secret` reference and no secret-store usage. grep for token/secret/from_s | WF-04 (publish credential in CI secret store, tag-scoped) presupposes a publish workflow, which does not exist. Vacuously not-violated but the operational requirement is unmet because the whole publish chain is absent. ⏳ gap (tied — 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 in .woodpecker.yml — the file has no `event: tag` step and no `CI_COMMIT_TAG`/pyproject-version/`__version__` comparison script. Publish flow explicitly deferred  | WF-05 (verify tag matches pyproject.version AND __version__ before upload) requires the publish workflow. Absent. ⏳ 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-06 | ✅ | No build/upload step in .woodpecker.yml; no `dist/` wheel handling; publish chain deferred (:5-6). | WF-06 (upload the wheel built fresh in the publish run) requires a build+upload step pair that does not exist. ⏳ 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-07 | ✅ | No pre-publish smoke step (ephemeral venv install of the built wheel + __version__ assert) anywhere in .woodpecker.yml; publish chain deferred (:5-6). | WF-07 (pre-publish wheel smoke) requires the publish workflow. Absent. Especially relevant here since the package ships a console script (entry-point smoke would be needed). ⏳ 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-08 | ✅ | No post-publish verify step polling the Codeberg REST API in .woodpecker.yml; publish chain deferred (:5-6). | WF-08 (poll `…/api/v1/packages/magogi-admin/pypi/<name>/<version>` for 200 after upload) requires the publish workflow. Absent. ⏳ 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-09 | ✅ | .woodpecker.yml image lines :22/:31/:48/:66 `python:3.12-slim`, :41 `python:3.11-slim`, :58 `python:3.13-slim` (rolling-minor pins — explicitly accepted by WORKFLOWS.md §7.1 for securit | Every external image is pinned to a specific version; the Python interpreter images use accepted rolling-minor and the plugin image is exact-pinned. Refute attempt found no `python:slim`, no `@latest`, no `@v8` floating tag. Diges |
| WF-10 | ✅ | .woodpecker.yml has eight steps (lint, typecheck, test-3.11/3.12/3.13, vuln-scan, secret-scan) and grep for `depends_on` returns NONE across the whole file. Woodpecker runs steps in par | All independent gates and the per-version test fan-out run in parallel — no `depends_on` serialises them. In the current gates-only graph there are no genuine inter-step dependencies (no build→publish edge exists because there is  |
| WF-11 | ⏳ | committed `uv.lock` not yet used by CI (`pip install -e .[dev,...]` resolves fresh). Proper fix = CI install from the lock (`uv sync --locked`), a uv-based restructure needing the Codeberg index+token that can't be verified end-to-end here (CI dormant). Fleet-wide gap (no sibling has closed WF-11) — deferred to a federation-level CI decision. |
| WF-12 | ✅ | .woodpecker.yml whole file — grep for `\|\| true` returns NONE; commands are listed literally (:26-27 `ruff check src tests`/`lint-imports`, :54 `coverage run --source=src/mgf -m pytest | Every step runs commands whose native non-zero exit propagates to the Woodpecker UI: no `\|\| true`, no error-swallowing, no green-on-skip. The exact command text is in the file. pip-audit fails loudly with no retry mask. Refute a |
| WF-13 | ✅ | .woodpecker.yml is a generated artifact — header "GENERATED — do not hand-edit", rendered from mgf-standard/templates/woodpecker/ by mgf-fed; not hand-maintained. |

### RELEASING

| Rule | Status | Evidence | Notes |
|---|---|---|---|
| REL-01 | ✅ | git cat-file -t v0.5.6 => 'commit' (lightweight tag), whereas every prior release tag v0.3.0..v0.5.5 => 'tag' (annotated). v0.5.6 is the PUBLISHED version (pyproject.toml:3 version="0.5 | REL-01 (RELEASING.md:33, §3.1): 'Every release MUST have a corresponding ANNOTATED git tag of the form v<version> on the exact commit that built the published wheel. Annotated tags only. Lightweight tags don't carry author/date/me — FIXED 2026-06-09: release tags re-annotated (v0.5.6) on the same build commits + force-pushed (annotated, GC-safe; no content change). 0 lightweight v-tags remain. |
| REL-02 | ✅ | dist/ contains only mgf_apiprobe-0.5.5-py3-none-any.whl + mgf_apiprobe-0.5.5.tar.gz (both built 2026-06-04); dist/.gitignore + root .gitignore:15 (`dist/`) gitignore it. CHANGELOG.md `# | REL-02's literal MUST: a version string MUST NOT be reused across different wheel contents. No version-string reuse or dist/ overwrite is evidenced — a single version's artifacts sit in dist/. Upheld. |
| REL-03 | ✅ | PUBLIC_API.md exists (/home/bassam/PycharmProjects/mgf-apiprobe/PUBLIC_API.md) but its header (lines 1-25) is only the contract-list/stability-tier/pinning preamble — no REL-03 banner.  | REL-03 (RELEASING.md:35): 'PUBLIC_API.md and PUBLIC_API.json reflect master HEAD, not the published surface... Consumers verify what they actually have with pip show + the __version__ field in PUBLIC_API.json. The doc carries a ba — FIXED 2026-06-08 (0.5.7): PUBLIC_API.md carries the master-HEAD banner + __version__ verify pointer |
| REL-04 | ✅ | grep -rEn 'pypirc\|codeberg_package_token\|TWINE_PASSWORD\|write:package\|from_secret' across *.yml/*.yaml/*.toml/*.md returned NO hits (exit 1). No .env in the tree. .woodpecker.yml ex | REL-04's MUST: publish tokens MUST NOT be passed via chat, shell history, or env vars in unmanaged sessions (and not committed). No token literal, no .env, no from_secret leak is present in-repo. Absence of a wired publish step is |
| REL-05 | ✅ | CHANGELOG.md shows distinct sequential versions 0.1.0→0.5.6 with no duplicate `## [X.Y.Z]` header (uniq -d = empty). No PKG-07 delete+re-upload note, no content-swap record anywhere in  | REL-05's MUST: a published version is immutable — fixes ship as a new version, never a silent content swap. No swap or re-publish-of-a-resolved-version is evidenced; the version line advances monotonically. Upheld. |
| REL-06 | ✅ | .woodpecker.yml header lines 4-6 state verbatim: 'No publish flow yet — when a release is cut, copy the tag-coherence -> smoke -> publish -> verify-pypi chain from mgf-common.' The pipe | REL-06 (RELEASING.md:38, §2): 'The release flow is strictly ordered: bump -> regenerate PUBLIC_API.json -> build -> test -> twine check -> commit -> tag -> push tag -> upload to Codeberg -> verify via REST.' Premise binds (mgf-api — FIXED 2026-06-08: tag→build→tag-coherence(pyproject+__version__)→smoke→publish→verify, in order |
| REL-07 | ✅ | `git show c98408d --name-only` (the `release: mgf-apiprobe 0.5.6` commit) lists ONLY CHANGELOG.md + pyproject.toml — FEEDBACK.md is NOT in the release commit. `git log --oneline -- FEED | REL-07's MUST: a release commit MUST close every FEEDBACK entry it ships. The 0.5.6 release ships zero FEEDBACK entries (none flipped in c98408d), so the obligation is vacuously satisfied for this release. Upheld. |
| REL-08 | ✅ | No pre-release smoke exists anywhere: .woodpecker.yml has no step that builds the wheel and `pip install dist/*.whl` into an ephemeral venv (the header at line 5 lists 'smoke' as part o | REL-08 (RELEASING.md:40, §2.2): 'Pre-release smoke MUST exercise the actually-built wheel. Run pip install dist/<package>-<version>-*.whl into an ephemeral venv and import every public top-level name.' Premise binds (a published w — FIXED 2026-06-08: the smoke step installs the built wheel into a fresh venv + imports mgf.apiprobe before publish |
| REL-09 | ✅ | The 0.5.6 release commit c98408d flipped no FEEDBACK status (only CHANGELOG.md + pyproject.toml changed). CHANGELOG [0.5.6] is a pure pin-walk with no consumer-facing migration. docs/cu | REL-09's MUST: every FEEDBACK status-flip in a release MUST produce a consumer-facing notification paragraph. The 0.5.6 release flips no entry, so no notification is owed — the obligation is vacuously satisfied for this release. U |

### PACKAGE_DISTRIBUTION

| Rule | Status | Evidence | Notes |
|---|---|---|---|
| PKG-01 | ✅ | pyproject.toml:80-81 [project.urls] point Homepage/Issues at codeberg.org/magogi-admin/mgf-apiprobe (good). uv.lock:846-847,863,877 resolve mgf-common 0.45.1 + mgf-test-supervisor 0.1.9 | Consumption side (lock + sources) is correct: mgf-* resolve only from Codeberg. But PKG-01 also requires that an mgf-* package be PUBLISHED to / surfaced from Codeberg, not pypi.org. The README still names pypi.org as where this p — FIXED 2026-06-08: publish-to-Codeberg pipeline added (resolve+publish via Codeberg) |
| PKG-02 | ✅ | [verify-upheld] pyproject.toml:271 url = "https://codeberg.org/api/packages/magogi-admin/pypi/simple/" — character-for-character the §3 canonical simple-index endpoint (owner magogi-adm | Tried to refute by hunting for a mistyped or alternate endpoint form; the only registry endpoint in the repo is the exact canonical simple-index URL, matching §3 verbatim. Upheld. |
| PKG-03 | ✅ | [verify-upheld] Token grep over working tree (token/password/secret/api-key = '<16+ chars>') finds only test fixtures: tests/unit/checks/test_security.py:135 secret = "very-secret-token | Ruthless secret hunt: no real write:package/read:package token, no pypi.org token, no OIDC ref committed. The only matches are test placeholders. Token discipline (never committed, env/secret-managed) is honored. The absence of a  |
| PKG-04 | ✅ | .woodpecker.yml:1-78 has steps lint/typecheck/test-3.11/3.12/3.13/vuln-scan/secret-scan only. Header comment lines 5-6: 'No publish flow yet — when a release is cut, copy the tag-cohere | PKG-04 requires a strictly-ordered publish flow targeting Codeberg. None is implemented (no publish pipeline). Gap, not declined. — FIXED 2026-06-08: the tag-gated build→...→publish chain is the ordered publish ritual |
| PKG-05 | ✅ | .woodpecker.yml has no verify-codeberg / REST-200 step. The header comment even names the stale target 'verify-pypi'. No GET .../api/v1/packages/magogi-admin/pypi/<name>/<version> check | No post-publish Codeberg REST verification exists. Gap, not a deliberate decline. — FIXED 2026-06-08: the verify-codeberg step polls the Codeberg REST API post-publish |
| PKG-06 | ✅ | [verify-upheld] pyproject.toml:269-276 — [[tool.uv.index]] name="codeberg-mgf", url=".../pypi/simple/", explicit = true; [tool.uv.sources] maps mgf-common = { index = "codeberg-mgf" } a | Tried to refute by finding (a) a committed bare --extra-index-url (none) and (b) a direct mgf-* dep NOT mapped in [tool.uv.sources] (none — both are mapped). The lock proves Codeberg resolution; explicit=true closes the dependency |
| PKG-07 | N/A | PKG-07 governs delete-and-re-upload of the same name+version during botched-upload recovery, recorded in CHANGELOG/release log. No publish pipeline exists and no evidence of any re-uplo | Immutability/re-upload-recovery is a release-time runtime behavior with no committed-artifact obligation absent a recovery event. Nothing to evidence. N/A for a repo without a publish flow and without a recorded recovery. |
| PKG-08 | N/A | PKG-08 (retention against the magogi-admin account quota; prune older minors) is an account/registry-level operational policy owned centrally (mgf-standard §8/§12). It is not a per- | Account-quota retention is a federation-admin responsibility, not something a consumer/leaf library like mgf-apiprobe owns or can evidence in-repo. N/A at this repo. |
| PKG-09 | ✅ | .woodpecker.yml:14-17 triggers on push/pull_request/manual only — no 'event: tag, ref: refs/tags/v*' publish step exists. No codeberg_package_token/codeberg_package_user secret is refer | PKG-09 requires a tag-driven, build-in-CI, secret-token-authenticated Codeberg publish step. Entirely absent. Per the task's framing (published mgf-* package with no pipeline → ⏳, not N/A). Gap. — FIXED 2026-06-08: tag-driven, build-in-CI, secret-token Codeberg publish step added |
| PKG-10 | ✅ | [verify-upheld] pyproject.toml:2 name = "mgf-apiprobe" (hyphenated PEP 503 dist name, NM-01). Wheel ships src/mgf as a PEP 420 namespace package ([tool.hatch.build.targets.wheel] packag | Tried to refute via a wrong import shape or a pypi.org canonical URL in [project.urls]; both are correct (dotted mgf.apiprobe namespace + Codeberg URLs). The lingering README.md:7 pypi.org metadata link is a residual-surface gap s |
| PKG-11 | N/A | PKG-11 (agent/federation version checks resolve against Codeberg, AG-09 amendment) targets the federation agent/recommendation tooling (mgf-common standards/agents CLI, gen_mgf_librarie | This rule binds on the agent/version-recommendation surface, which mgf-apiprobe does not implement. N/A for this leaf. |
| PKG-12 | ✅ | Residual pypi.org publish/distribution surface for the mgf-* package persists: README.md:7 links 'this package's [PyPI metadata](https://pypi.org/project/mgf-apiprobe/)' as the live sou | PKG-12 forbids residual pypi.org publish/distribution surface for mgf-* and is enforced by a copied grep gate. Both halves fail: live mgf-* pypi.org references remain (README:7 is a live distribution-of-record claim; SECURITY:3 li — FIXED 2026-06-08: README PyPI-metadata link off pypi.org → Codeberg (0 refs remain) |

### DOCUMENTATION

| Rule | Status | Evidence | Notes |
|---|---|---|---|
| DOC-01 | ✅ | Root listing: README.md, LICENSE, CHANGELOG.md, CONTRIBUTING.md, SECURITY.md, FEEDBACK.md, AGENTS.md, STARTHERE.md, DEPS.md, FEDERATION.md all present (ls of /home/bassam/PycharmProject | DOC-01's enumerated uniform ten-doc baseline + docs/ dir is fully satisfied for a sibling. The only library-only artifact still missing is PUBLIC_API.json — but that machine-companion gap is the substance of DOC-08 (which also gov |
| DOC-02 | ✅ | six-bucket hierarchy present — `docs/{standards,recipes,inprogress,claude,cutover}/` each with a README charter. |
| DOC-03 | ✅ | docs/claude/README.md, docs/recipes/README.md, docs/inprogress/README.md, docs/standards/README.md, docs/cutover/README.md all exist with charter text (verified first-lines: each states | DOC-03 requires every long-lived bucket to carry its own README.md charter. docs/testing/ is such a bucket and lacks one. Smallest fix: add docs/testing/README.md with a one-paragraph charter ('what goes here: testing/diagnostic p — FIXED 2026-06-08: docs/testing/README.md charter (the one bucket missing it) |
| DOC-04 | ✅ | CHANGELOG.md header cites Keep a Changelog v1.1.0 + SemVer + AP-03 0.x window. `grep '^## \['` yields an [Unreleased] section plus dated per-release entries 0.5.6→0.1.0, every one dated | Upheld. Format and per-release dated discipline confirmed; public-surface releases (0.5.0) carry Added sections naming new symbols. Same-commit enforcement is a git-history/process matter outside the artifact; the artifact is conf |
| DOC-05 | ✅ | docs/cutover/README.md exists with a full charter (What goes here / does NOT / Index) and Index states 'Empty — no breaking changes shipped yet.' `grep '^### Removed' CHANGELOG.md` → NO | Upheld. DOC-05 binds only when a breaking change removes/renames/reshapes a documented surface. No such change has shipped (no ### Removed, no rename), so no v<X.Y.Z>.md guide is owed; the bucket + charter README are correctly in  |
| DOC-06 | ✅ | All three trackers carry the §1 You are here → §2 Priority table → §3 Invariants → §4 Work units → §5 Closed items → §6 Notes on methodology shape (grep of headings confirms each). Each | Upheld. Canonical §1–§6 shape, file:line citations that resolve, and falsifiable concrete-output bullets are all present per §3.1/§3.2. [verify-upheld] |
| DOC-07 | ✅ | docs/claude/CLAUDE.md present (318 lines), dense-lookup format with the 'BEGIN mgf-common auto-generated' managed block, '**Project kind:** cli', and the agent-briefing pointer. Non-emp | Upheld. The required docs/claude/CLAUDE.md is present in dense-lookup format at the canonical path — DOC-07's presence MUST is met. The stray pre-move docs/CLAUDE.md (with stale L1 framing) is a DOC-07 'stale items' / DOC-12 hygie |
| DOC-08 | ✅ | No PUBLIC_API.json anywhere in the repo (find . -name PUBLIC_API.json excluding .venv → empty; not at root, not under src/, not in dist/). PUBLIC_API.md exists and is pinned to __all__  | DOC-08 requires the machine-readable PUBLIC_API.json companion generated from __all__ at every release AND pinned in CI (the second of the two pins, machine-companion drift / RA-10), plus __version__ matching. Only the first pin ( — FIXED 2026-06-08 (0.5.7): PUBLIC_API.json + tools/generate_public_api_json.py + pin test (PUBLIC_API.md already existed) |
| DOC-09 | ✅ | Direction (a) CI lint present: tests/unit/test_public_api_doc.py asserts every name in __all__ across 12 enumerated public modules (mgf.apiprobe + exceptions/config/core/core.matchers/a | Upheld. DOC-09's MUST floor is satisfied by EITHER (a) a name-existence CI lint OR (b) a back-reference; the PUBLIC_API.md↔__all__ parametrized test in the Woodpecker matrix supplies (a). The behavioral-verification clause (v2.16) |
| DOC-10 | ✅ | FEEDBACK.md is the consumer-facing flow (header: 'Paper-tracking file… Consumer projects file PAPER-NN', §1 Process, severity/lifecycle). The three docs/inprogress/*.md are internal RA/ | REFUTED. DOC-10 requires FEEDBACK.md be the consumer-facing flow and docs/inprogress/ the internal posture, not conflated. The internal-posture surface (inprogress/README.md) actively misroutes consumer signal AWAY from the repo's — FIXED 2026-06-08: FEEDBACK.md now states the consumer-facing-vs-docs/inprogress-internal routing |
| DOC-11 | ✅ | docs/inprogress/README.md index marks all three trackers 'v0.1 — active' with open §4 work units (RA-01..07, SH-01..07, PC-01..08). No docs/archive/ exists. No tracker is fully-closed-a | Upheld. DOC-11 is a SHOULD/maintenance signal; trackers are still active with open items, so no archival is owed and no fully-closed stranded tracker exists. [verify-upheld] |
| DOC-12 | ✅ | Intra-repo cross-references are relative links: README.md:55 links docs/inprogress/MGF_STANDARDS_CONFORMANCE.md and README.md:63-65 link DESIGN.md/HANDOFF.md/LIFT_CHECKLIST.md relativel | DOC-12's three MUSTs (relative intra-repo links, hierarchical headings, agent-navigable structure) are met; the only URL links point to a different repository where a relative path is impossible and a URL is the correct form. |
| DOC-13 | ✅ | FEEDBACK.md header defines the split — 'mgf-apiprobe-specific → file HERE; Federation-wide → file in mgf-common/FEEDBACK.md' — cites FB-01..FB-04/DOC-13, states local PAPER-NN numbering | Upheld on DOC-13's actual MUST: FEEDBACK.md is correctly repo-scoped with the sibling-vs-federation routing rule. (Caveat: the claim's extra assertion that 'inprogress/README also routes consumer signal correctly' is false — that  |
| DOC-14 | N/A | DOC-14 / ADP-04 (DOCUMENTATION.md lines 39, 66) explicitly name mgf-apiprobe in the federation-sibling carve-out: 'Federation siblings (mgf-fastapi, mgf-http, mgf-sqlalchemy, mgf-alembi | The rule's premise binds only consumer applications. mgf-apiprobe is a federation sibling, expressly carved out by name; its adoption relationship lives in mgf-common's federation_roadmap.md + its own CHANGELOG. Correctly N/A. (RE |
| DOC-15 | ✅ | docs/inprogress/MGF_STANDARDS_CONFORMANCE.md exists; §1 declares 'Declared conformance level: L2 (per CFM-02)'. README.md line 55 declares 'Conformance: L2' and links the tracker in the | Upheld. DOC-15 binds the EXISTENCE of an MGF_STANDARDS_CONFORMANCE.md with a declared level (L2) and per-rule markers, README-linked and same-place-declared — all present and L2-consistent between README and tracker. The 'pending  |
| DOC-16 | ✅ | DEPS.md at repo root titled 'DEPS — mgf-apiprobe's bidirectional dependency manifest' with §1 'What mgf-apiprobe depends on' (mgf-common/httpx/pydantic/jsonpath-ng/jmespath + extras tab | Upheld. The required bidirectional manifest (§1 depends-on / §2 depended-on-by / §3 maintenance) is present at repo root per DOC-16/v2.12, replacing USERS.md. [verify-upheld] |
| DOC-17 | ✅ | FEDERATION.md at repo root titled 'FEDERATION — pointer'; body: 'The federation contract is not maintained here… Read the contract at mgf-common/FEDERATION.md… Per DOC-17, siblings and  | Upheld. DOC-17 requires every non-mgf-standard project to ship FEDERATION.md as a pointer stub, not a copy; this is exactly that. [verify-upheld] |
| DOC-18 | ✅ | The load-bearing coupled surface for this tool — public symbols ↔ PUBLIC_API.md — is mechanically pinned in CI via tests/unit/test_public_api_doc.py (md must list every __all__ name), s | DOC-18 requires coupled surfaces to be updated same-commit and, where mechanizable, pinned. The mechanizable coupling that actually applies to this sibling (public symbol ↔ PUBLIC_API.md) is pinned by an executing test. The one un |
| DOC-19 | ✅ | LESSON_LEARNED.md present at repo root, append-only dated-log format with the DOC-19 template header (newest-first, supersede-not-rewrite, cites DOC-19 + lesson-learned-md-template), an | Upheld. DOC-19 (MUST since v2.21) requires a root LESSON_LEARNED.md; a seeded file with no real lessons yet is explicitly conformant per the rule ('presence is the bar'), and it is present at the canonical path. [verify-upheld] |

### OPERABILITY

| Rule | Status | Evidence | Notes |
|---|---|---|---|
| OP-01 | ✅ | rich `--version` — package + git SHA + Python + mgf-common/httpx (`cli/__main__.py:_rich_version`). |
| OP-02 | ✅ | `apiprobe doctor` self-check ships + wired + tested (`cli/doctor.py`; `test_doctor_returns_zero`). |
| OP-03 | ✅ | pyproject.toml:80-81 `Homepage`/`Issues` point at real Codeberg URLs (`codeberg.org/magogi-admin/mgf-apiprobe[/issues]`) — no placeholder. The CLI parser description (cli/__main__.py:31 | MUST: project URLs MUST resolve AND CI MUST verify (an HTTP-HEAD lint, or at minimum a 'no github.com/<placeholder>' grep). The URLs themselves are correct, but the mandated CI verification is entirely absent. Smallest fix: add a — FIXED 2026-06-08: CI no-placeholder grep added to the lint step |
| OP-04 | ✅ | headline version coherent — `_version.py` == `pyproject.toml` == 0.5.7 (drift resolved). |
| OP-05 | ✅ | `apiprobe explain` — effective config with env/default provenance, secrets redacted (`cli/explain.py`). |
| OP-06 | N/A | The tool writes NO persistent log file. The only logging is `logging.getLogger("mgf.apiprobe.suite")` (core/suite.py:51) used for in-process severity-promotion/diagnostic messages — the | OP-06's premise is a rotating log FILE on disk that the operator should not need a path to reach. This stateless verification CLI emits no such file — its output is the report on stdout (already path-free) and any logger records f |
| OP-07 | ✅ | `apiprobe bundle` — single diagnostic tarball: system info + redacted config + doctor (`cli/bundle.py`). |
| OP-08 | N/A | The tool writes no persistent state of any kind: grep for `open(`/`mkdir`/`write_text`/`atomic_write` under src/mgf/apiprobe/ returns nothing; there is no crash dir, no log rotation, no | OP-08 governs bounded growth of on-disk state directories (crash reports, log rotations, caches). This stateless CLI/library creates no such directories — there is nothing whose growth could fill the user's disk. The premise genui |
| OP-09 | N/A | Rules box marks OP-09 `applies to: service`. mgf-apiprobe is a CLI + library API-verification tool (pyproject.toml:86-88 console scripts `mgf-apiprobe`/`apiprobe`; SCOPE.md:62), not a d | OP-09 (production safety guards refusing dev-shaped values, fail-fast before the listener opens) is a service-shape rule. This tool is invoked on demand by a user/CI and exits; there is no production boot to guard. The prompt itse |
| OP-10 | N/A | Rules box marks OP-10 `applies to: service`. mgf-apiprobe ships as a Python wheel/sdist (build-system hatchling, pyproject.toml:90-98) installed via pip from the Codeberg registry — the | OP-10 (deployable artefacts carry a stable version tag instead of `:latest`; rollback runbook) is a service/deployment rule about container images in production manifests. This is a distributed library+CLI, not a deployed artefact |
| OP-11 | N/A | Rules box marks OP-11 `applies to: service`. There is no alerting surface: no Prometheus rules, no alertmanager config, no runbooks dir (grep found no docs/runbooks/, no `runbook_url`,  | OP-11 (every alert pages a human + links a runbook) presupposes a deployed service with an alerting pipeline. A user/CI-invoked verification CLI has no alerts to wire. The premise does not bind. |
| OP-12 | N/A | Rules box marks OP-12 `applies to: service`. The tool persists no data (see OP-08 evidence: no on-disk state, no datastore, no S3/R2/GCS target); there is nothing to back up or restore. | OP-12 (backup + restore drill against the real target) presupposes a stateful service with a production datastore. A stateless verification CLI/library has no persistent data and no backup target. The premise does not bind. |

### DEPLOYMENT

| Rule | Status | Evidence | Notes |
|---|---|---|---|
| DEP-01 | N/A | DEPLOYMENT.md:7-9 scopes the standard to 'stateful web-service consumer applications'; DEP-01 'Applies to: service' (DEPLOYMENT.md:41). pyproject.toml:2-5 declares mgf-apiprobe as a pub | mgf-apiprobe is a pip-installed library + CLI console script (project.scripts in pyproject.toml), not a stateful web service provisioned onto cloud infrastructure. There are no cloud resources (VMs, LBs, buckets, DNS) for this too |
| DEP-02 | N/A | DEPLOYMENT.md:42 DEP-02 'Applies to: service'; scope DEPLOYMENT.md:7-9. No ansible/, chef/, salt/, Dockerfile-deploy, or any VM/container production state exists. The package is distrib | There is no production VM or container image whose state this tool owns. Configuration-as-Code governs packages installed on production VMs of a running web service; a pip-installed CLI has no such VM state to express idempotently |
| DEP-03 | N/A | DEPLOYMENT.md:43 DEP-03 'Applies to: service'; the rule is about deploy-time artefacts ('no pip install --upgrade at runtime in production', 'a deploy installs only from the lock'). mgf | DEP-03 governs the immutability of artefacts deployed to a production environment of a web service. A published library/CLI has no production deploy that installs from a lock; its release-artefact immutability is the PKG/REL bound |
| DEP-04 | N/A | DEPLOYMENT.md:44 DEP-04 'Applies to: service'; lists DB credentials, signing keys, TLS private keys, OAuth secrets in Ansible Vault / cloud KMS for a production VM/service. mgf-apiprobe | There are no production secrets that this package deploys or stores at rest. The tool consumes target-API credentials supplied by its operator at runtime; that secret-handling conduct is judged under SECURITY (SC family) — not DEP |
| DEP-05 | N/A | DEPLOYMENT.md:45 DEP-05 'Applies to: service'; the rule concerns deploy/scripts/deploy.sh\|backup\|restore\|rollback taking a prod/staging/dev env arg (DEPLOYMENT.md:352-379). No deploy | DEP-05 binds operator deploy/backup/restore/rollback scripts of a web service to an environment argument. mgf-apiprobe has no such deployment scripts. Its CLI is an API-verification entry point, not a deploy script, so the environ |
| DEP-06 | N/A | DEPLOYMENT.md:46 DEP-06 'Applies to: service'; canonical shapes are blue/green, rolling, atomic-symlink, container-tag-swap, snapshot-restore (DEPLOYMENT.md:394-412) — all production ro | Reversible-deploy / rollback discipline governs putting a running web service into production. A published CLI/library has no production rollout to reverse — a 'rollback' for a package is publishing a prior version (REL/PKG concer |
| DEP-07 | N/A | DEPLOYMENT.md:47 DEP-07 'Applies to: service'; mandates a top-level deploy/ with README/terraform/ansible/scripts/monitoring/docs (DEPLOYMENT.md:151-192). ls confirms no deploy/ directo | The deploy/ directory shape is required of 'every web-service consumer' (DEP-07 text). mgf-apiprobe is a library+CLI package, not a web-service consumer with cloud deployment artefacts, so the deploy/ shape requirement has no subj |
| DEP-08 | N/A | DEPLOYMENT.md:48 DEP-08 'Applies to: service'; requires metrics/logs/traces flowing to a queryable sink, a committed deploy/docs/slo.md, error-budget + burn-rate alerts paging a human c | End-to-end production observability (SLO file, burn-rate alerts, paging) governs a running production web service. A CLI/library has no production runtime emitting metrics to a sink an operator queries; its own logging/finding-rec |
| DEP-09 | N/A | DEPLOYMENT.md:49 DEP-09 'Applies to: service'; requires DNS records in IaC/committed list and auto-renewed TLS certificates with expiry monitoring for the deployed service's hosts. mgf- | DNS + TLS as managed infrastructure governs the edge of a deployed web service. A pip-installed CLI tool has no production hostname, DNS records, or server TLS certificates of its own. The premise does not bind. (TLS verification  |
| DEP-10 | N/A | DEPLOYMENT.md:50 DEP-10 'Applies to: service'; requires deploy/docs/first-production-cut.md documenting the green-field provisioning sequence (terraform apply, ansible playbooks, DNS cu | A first-production-cut runbook documents provisioning a web service onto cloud infrastructure end-to-end. mgf-apiprobe has no infrastructure to provision — it is installed via pip from the registry. The runbook requirement has no  |
| DEP-11 | N/A | DEPLOYMENT.md:51 DEP-11 'Applies to: service'; requires deployability to >=2 environments (prod + staging/dev) from the same IaC + config-management code, parameterised by env files (DE | Multiple-environments-from-the-same-code governs a deployed web service's prod/staging IaC parameterisation. A published library/CLI is installed identically wherever the consumer runs it; it has no prod/staging cloud environments |

### PRESENTATION_LAYER

| Rule | Status | Evidence | Notes |
|---|---|---|---|
| PR-01 | ✅ | src/ has ZERO third-party UI-framework imports: grep for click/typer/fire/rich/textual/prompt_toolkit/PySide6/PyQt6/flask/fastapi/django across src/ returns nothing; CLI uses only stdli | PR-01 always applies (standard §7, §8.2 — even single-UI/no-UI siblings). The no-UI-framework fact is met, but the MUST 'enforced mechanically via import-linter' is unmet — there is no forbidden-modules contract listing the UI fra — FIXED 2026-06-08: added a 3rd import-linter contract forbidding UI frameworks (PySide6/PyQt/textual/tkinter) — the clause(b) mechanical enforcement; 3 kept/0 broken |
| PR-03 | N/A | mgf-apiprobe ships exactly ONE UI consumer: the CLI under src/mgf/apiprobe/cli/ (checks.py, run.py, doctor.py, _default_suite.py, __main__.py). There is no second UI (no Qt/GUI, no web, | PR-03's premise is 'An app repo with multiple UIs'. PR-02 (and §7 'For a sibling without an app today', §8.2) state PR-02..PR-05 activate at the SECOND UI consumer. The standard §8.2 names mgf-apiprobe explicitly: 'federation libr |
| PR-04 | N/A | PR-04 enforces 'The layer hierarchy' (core/view/ui contracts (a) and (b)) for 'an app repo with multiple UIs'. mgf-apiprobe has one UI (the CLI) and no view/ or ui/<framework>/ tree to  | PR-04's subject ('the layer hierarchy' from PR-03, contract (b) about ui/<framework> not importing peer ui/<other>) presupposes the multi-UI three-layer split that PR-03 establishes. With a single UI and no view/ui split, there is |
| PR-05 | N/A | PR-05 governs 'Each ui/<framework>/ adapter MUST consume view/ only — never another ui/<other> adapter.' mgf-apiprobe has a single UI (src/mgf/apiprobe/cli/) and no sibling UI to cross- | The premise (≥2 sibling UIs) does not exist. PR-05 is in the PR-02..PR-07 band that §8.2 marks N/A for mgf-apiprobe until a multi-UI consumer materialises. Genuinely non-binding for a single-CLI tool. |
| PR-07 | N/A | PR-07: 'A sibling at L1+ with a UI consumer MUST have a PR — PRESENTATION_LAYER section in its MGF_STANDARDS_CONFORMANCE.md. A pure-SDK sibling with zero UI consumers MAY mark PR-02..PR | PR-07 (the tracker-classification MUST) is itself listed in the PR-02..PR-07 band that §8.2 marks N/A for single-UI federation libraries including mgf-apiprobe by name. The library has one UI (CLI), not a multi-UI app, so the dedi |

### AGENTS

| Rule | Status | Evidence | Notes |
|---|---|---|---|
| AG-01 | ✅ | /home/bassam/PycharmProjects/mgf-apiprobe/AGENTS.md (36 lines) is a thin pointer: 'Run `mgf-common agents`', states 'do not edit it; project-specific agent notes belong in this project' | AG-01 MUST (thin pointer at root, federation-identical, no briefing copy, notes go to docs/claude/CLAUDE.md) literally satisfied; no counterexample found. [verify-upheld] |
| AG-02 | ✅ | AGENTS.md:9 points at single source `mgf-common agents`. docs/claude/CLAUDE.md:3-7 carries the BEGIN/END 'mgf-common auto-generated' markers + a 'Project-specific lookup for Claude sess | Canonical briefing deferred to `mgf-common agents`; project-scoped lookup in docs/claude/CLAUDE.md auto-block per AG-02. Upheld. [verify-upheld] |
| AG-03 | ✅ | .gitmessage:9-10 wires BOTH trailers: 'Signed-off-by: Bassam Alsanie <bassam@magogi.org>' AND 'Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>'. Recent commits fe19 | AG-03 MUST = both signing trailers present with canonical Signed-off-by identity + Co-Authored-By model/context string. Literally satisfied in template and agent-authored commits. The author-email divergence does not refute AG-03  |
| AG-04 | ✅ | /home/bassam/PycharmProjects/mgf-apiprobe/FEEDBACK.md (22KB) ships §1 Process ('File freely. Any consumer hitting friction MUST file a PAPER-NN'), the `mgf-common feedback` pipeline, st | AG-04 MUST (file reusable friction as a FEEDBACK paper via mgf-common feedback) supported as a repo capability that is instantiated. Upheld. [verify-upheld] |
| AG-05 | N/A | AGENTS.md §9 Mechanical enforcement: "AG-05 \| Self-enforcement; runtime memory subsystem already prompts the agent to verify." | AG-05 ("verify memory claims before recommending action") binds an agent's in-session behavior, not a repo artifact. There is no checkable file/line in mgf-apiprobe that can be MET/⏳ for it — the standard itself marks it self-enfo |
| AG-06 | N/A | AGENTS.md §9: "AG-06 \| Runtime / harness enforcement (permission prompts on Bash, MCP tool calls). Not a code rule." §6 table of reversibility. | AG-06 (risky-operation confirmation) is enforced by the runtime/harness permission layer during a live session, not by any artifact the repo ships. The standard explicitly states "Not a code rule." No file:line can demonstrate or  |
| AG-07 | N/A | AGENTS.md §9: "AG-07 \| Self-enforcement; runtime reminders surface stale task lists." | AG-07 (use TaskCreate/TaskUpdate for ≥3-step work) governs an agent's session-time task tracking, surfaced by runtime reminders. There is no repo artifact in mgf-apiprobe that can be MET or unmet for it. Premise binds agent sessio |
| AG-08 | N/A | AGENTS.md §9: "AG-08 \| Self-enforcement; runtime auto-memory rules cover this." §5 Save/Do-not-save lists. | AG-08 (memory writes federation-scoped, not session-scoped) is a memory-discipline rule for the agent runtime — the auto-memory subsystem, not anything mgf-apiprobe ships. No checkable file:line in the repo. Premise does not bind  |
| AG-09 | N/A | AGENTS.md §9: "AG-09 \| Review-only." Rule text: verify sibling versions against the Codeberg registry, not local dist/. | AG-09 binds an agent's verification step when recommending a sibling-version action; the standard classes it review-only with no mechanical/code artifact. mgf-apiprobe does pin mgf-common via [tool.uv.sources] codeberg-mgf index ( |
| AG-10 | N/A | AGENTS.md §9: "AG-10 \| Review-only. A PR that 'fixes documentation' without a paper link is the trigger for a reviewer prompt." §7 standards-drift. | AG-10 (drift found → file a PAPER, never silently edit doc/code to match) governs how an agent responds to discovered drift; classed review-only with no checkable repo artifact. mgf-apiprobe ships a FEEDBACK.md (the correct channe |
| AG-11 | ✅ | FEEDBACK.md header encodes routing: 'mgf-apiprobe-specific (probe shape, check behaviour, matcher semantics, Suite execution) → file HERE' and 'Federation-wide (cross-sibling patterns,  | AG-11 MUST (route project-specific friction to target's FEEDBACK.md, cross-cutting to mgf-common, with enough to triage+act) documented and instantiated. Upheld. [verify-upheld] |
| AG-12 | ✅ | pyproject.toml:43 declares 'mgf-common>=0.41,<0.47' (always installed), which provides `mgf-common agents --project`. docs/claude/CLAUDE.md houses the project-scoped content (auto-block | AG-12 MUST (expose project-scoped briefing via mgf-common agents --project, content in docs/claude/CLAUDE.md, dependency declared) satisfied. Upheld. [verify-upheld] |
| AG-13 | N/A | AGENTS.md AG-13: "Only the mgf-common supervisor may change a library; other projects MUST NOT — they file a request in the target library's FEEDBACK.md." mgf-apiprobe ships FEEDBACK.md | AG-13 governs cross-project change behavior: a sibling/consumer wanting another library changed must file a paper, not edit it. This binds the agent's action when it wants a *sibling* changed — not a self-checkable artifact in mgf |
| AG-14 | ✅ | release-commit coherence — `__version__` (`_version.py`) synced with `pyproject.toml`; no drift. |
| AG-15 | N/A | AGENTS.md §9: "AG-15 \| Review-only (the charter grants license, not a checkable artifact). ... A PR that silently skips a MUST ... is the trigger for a reviewer prompt." §10 Charter de | AG-15 (agents empowered to push back/propose/decline-with-rationale; must know the Charter and use the channels) is explicitly "Review-only ... grants license, not a checkable artifact." The DOC-18 mechanical backstop (charter fil |
| AG-16 | ✅ | pyproject.toml dependencies (lines 42-48) lists mgf-common>=0.41,<0.47 with NO [standards] extra; the dev extra (lines 56-77) declares mgf-test-supervisor but NOT mgf-common[standards]; | AG-16 ("Every project MUST keep the standards corpus resolvable to its agents — depend on mgf-common[standards]"). mgf-apiprobe depends on plain mgf-common only; nowhere does it declare mgf-common[standards] (the dev/tooling extra — FIXED 2026-06-08: separate [standards] extra (mgf-common[standards]; OUT of [dev]) |
| AG-17 | ✅ | docs/memory/MEMORY.md present (the project memory index). |
| AG-18 | ✅ | my_stuff/ git-ignored + .githooks/prepare-commit-msg present (auto-adds the Signed-off-by trailer). |
| AG-19 | N/A | no runtime auto-memory store for this project yet (~/.claude/projects/<slug>/memory/ absent) — nothing to VCS-track; binds only once such a store exists. |
| TM-01 | ✅ | UTC at boundaries — `datetime.now(UTC)` (suite.py:196/207/319 report start/finish; factories/builtins.py:30). |
| TM-02 | ✅ | ISO-8601/Z wire format — factories/builtins.py:35 `isoformat().replace("+00:00","Z")`. |
| TM-03 | ✅ | request duration via a monotonic clock — `elapsed_ms` delegates to httpx `r.elapsed` (httpx_transport.py:153). |
| TM-04 | ✅ | the `iso_timestamp` factory takes an injectable `when=`; suite start/finish are report-metadata stamps, not time-dependent logic. |
| TM-07 | N/A | UTC only; no IANA timezone-name usage. |
| TM-08 | ✅ | async sleep uses `asyncio.sleep` (suite.py:545 retry backoff), not blocking `time.sleep`. |
| PF-01 | ⏳ | perf tests use in-file thresholds (test_suite_throughput.py:22) but not the recorded-baseline regression shape — no tests/perf/baselines.json. |
| PF-02 | ✅ | perf tests marked `@pytest.mark.perf` (5 files; marker registered in pyproject). |
| PF-03 | ⏳ | no tests/perf/baselines.json — baselines not recorded. |
| PF-04 | N/A | no re-baselining flow yet (activates once PF-03 baselines exist). |
| PF-05 | ⏳ | perf tests are plain-pytest timing, not a warm-up / min-sample / statistical harness. |
| PF-07 | ✅ | perf failures surface the comparison numerically (budget f-string messages). |
| PF-08 | N/A | thresholds are relative-drop, not hardware-tier-sensitive absolute values. |
| OB-01 | N/A | probe library, not a monitored service — no metrics pillar. |
| OB-02 | N/A | no metrics. |
| OB-03 | N/A | no metrics. |
| OB-04 | N/A | creates correlation spans (`operation_span`) but is not a trace-exporting service. |
| OB-05 | N/A | no service SLIs. |
| OB-07 | N/A | no alerts. |
| OB-08 | N/A | no SLI/SLO/alert definitions. |
| OB-09 | N/A | consumes `mgf.common.observability` LogRecord; mgf-common owns the schema. |
| OB-10 | N/A | emits via mgf-common's formatter; does not own a wire shape. |
| OB-11 | N/A | consumes mgf-common's LogStatsCollector; doesn't own it. |
| NM-01 | ✅ | dist `mgf-apiprobe` (hyphen). |
| NM-02 | ✅ | dotted import `mgf.apiprobe`. |
| NM-03 | ✅ | Codeberg slug `mgf-apiprobe` (hyphen). |
| GUI-01 | ✅ | imports no Qt (0 hits). |
| GUI-02 | N/A | no GUI (library + CLI). |
| GUI-03 | N/A | no GUI workers. |
| GUI-04 | N/A | no GUI workers. |
| GUI-05 | N/A | no Qt / GUI main(). |
| GUI-06 | N/A | no presentation widgets. |
| GUI-07 | N/A | no streaming GUI. |
| GUI-08 | N/A | no GUI-state persistence. |
| GUI-09 | N/A | no GUI tests. |
| GUI-10 | N/A | no GUI capability-gating. |
| REL-10 | ✅ | cohort-aware — pinned to mgf-common; participates in cohort-walk releases on a pin break. |
| REL-11 | ✅ | released via the federation Phase A/B cohort-release flow. |
| REL-12 | N/A | binds the cohort Phase-A agent's pytest-denial handling, not a released sibling's code. |
| REL-13 | ✅ | releases pass the federation consistency gate (`mgf-fed registry --check`). |
| FB-05 | ✅ | cross-repo feedback flows through the `pending-feedback/<target>.md` outbox + the supervisor relay (`mgf-fed feedback`), never a direct edit (FB-05). |


---

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

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