# Magogi Foundation Standards — Conformance Tracker (mgf-test-supervisor)

> **Status.** v0.1 — initial audit. Created 2026-05-27 per the federation L2-floor pass.
> **Scope.** mgf-test-supervisor'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),
> [`mgf-standard/docs/standards/TESTING.md`](https://codeberg.org/magogi-admin/mgf-standard/src/branch/main/docs/standards/TESTING.md) §19 (the supervisor's own home standard — rules TS-22..TS-27).

---

## §1 You are here

**Project shape:** federation test supervisor — budget-aware, crash-survivable, resumable pytest driver. Stdlib-only library + CLI (`mgf-test-supervisor`, alias `mtest`). Public Python surface: `mgf.test_supervisor` (TestRecord schema, MARKER_TIER, supervisor entry point).

**Current version:** 0.1.13.

**Place in the federation:** sibling library. mgf-common is a **dev-only** dependency (test runner + alignment pin verification); no runtime mgf-common surface is imported. This is structural — TS-23 mandates the supervisor stays stdlib-only so it can drive pytest in any consumer's environment without dragging optional deps.

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

mgf-test-supervisor pins `mgf-common>=0.41,<0.42` in its `[dev]` extras (alignment-pin verification + the standards corpus it audits against).

**Applicable standards groups (rules audited):** DP, EH, AP, TS, DOC, REL, NAMING, AGENTS, TIME, PERFORMANCE, OBSERVABILITY (output side only — see §3 carve-outs).

**N/A standards groups (rule premise doesn't apply to this project's shape):**
- **DEP** — library, not a stateful service.
- **CF** — no app-runtime config; CLI argparse only. No `MgfSettings` surface (would require mgf-common runtime dep, violating TS-23).
- **GUI_CONSUMERS** — CLI-only.

**Partially N/A** (see §3 for the declined rows):
- **LG / OBSERVABILITY** — supervisor stays stdlib-only per TS-23; emits structured JSONL via direct writes, not via `mgf.common.observability`. The output side (TestRecord JSONL schema, deterministic test_id, structured fields) IS audited; the consumer-of-LG-* rules are declined per non-adoption-is-valid.
- **SC** — applies to subprocess + signal management; secrets/redaction rules N/A (the supervisor reads no secrets).

**Counts (2026-06-07 — first evidence-based depth audit, all 259 MUSTs (PAPER-100 re-baseline 2026-06-11)):**

| Priority | Count |
|---|---|
| ✅ verified (file:line, refute-survived) | **110** |
| ⏳ open MUST gaps | **1** |
| N/A (premise doesn't bind this stdlib-CLI shape) | **106** |
| 🚫 declined-with-rationale | **1** (TS-06 — see §3) |

Applicable (non-N/A) = **113**; **103/112 (92%) evidenced.** Remaining 9 ⏳: TS-06 (coverage 45→80, subprocess-heavy — candidate CFM-04 decline), TS-18 (slow-marker + slow-suite CI step), AP-02 (per-name usage examples), OP-01 (rich --version), OP-08 (.gates retention doc), SC-04, SC-15, REL-01 (lightweight-tag re-annotate, needs auth), WF-11 (install-from-lock, federation-shared). (13 of the original ⏳ were depth-audit MISLABELS — refute-pass status/rationale mismatch — reconciled to ✅; see §Z notes.) CFM-02 **L2 requires every MUST** — so the prior "Green / ≥90% by construction" estimate was **optimistic and is now falsified by evidence**: being built FROM the standards covered the design-principle/error/time families well (those largely hold), but the library-hygiene families (API surface, CI publish, scope, and the supervisor's OWN testing conformance) were never actually evidenced. The 105 N/A are real and validated (CF 12/12, DEP 11/11, LG 17/17 — correct for a stdlib CLI with no runtime mgf-common surface).

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

| Cluster | Rules | Count |
|---|---|---|
| TESTING — self-conformance (tiers/mirror/property/leakage/supervisor-in-own-CI) | TS-01, TS-02, TS-03, TS-04, TS-05, TS-06, TS-13, TS-16, TS-17, TS-18, TS-19, TS-20, TS-21, TS-22, TS-23, TS-24, TS-25, TS-27, TS-28 | 19 |
| CI publish pipeline (no tag-driven chain; stale 0.1.10 wheel in dist/) | REL-06, REL-08, WF-02, WF-03, WF-04, WF-05, WF-06, WF-07, WF-08, WF-11 | 10 |
| API surface (no __all__ / PUBLIC_API.md / tiers / private-import contract) | AP-01, AP-02, AP-05, AP-08, AP-10, AP-11, AP-14 | 7 |
| SCOPE policy absent (SP-01..06) | SP-01, SP-02, SP-03, SP-04, SP-05, SP-06 | 6 |
| misc (corpus-pin, ops, docs, security, tag, layering) | AG-16, DOC-04, DOC-09, OP-01, OP-08, PR-01, REL-01, SC-04, SC-15 | 9 |

**2026-06-07 depth audit provenance.** 16-family auditor fan-out + adversarial refute on every ✅ (~43 agents over two workflow runs + a 9-id micro-audit). The first run's TESTING/PRESENTATION auditors copied this ledger's all-⏳ scaffold instead of auditing, and six large families truncated; a completeness check caught it and re-ran those with a hardened "do NOT read the scaffold" prompt. Four auditor-🚫 verdicts (AP-01/10/11, REL-01) were reclassified ⏳ — they are unmet, not deliberate CFM-04 declines. Per-rule verdicts with file:line are in §Z; this supersedes the 2026-05-27 by-construction estimate.


## §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)

Highlight: the supervisor's `MockProvider` + `subprocess` boundary is DP-02 provider-seam-shaped — every external process call goes through a uniform `subprocess.run(...)` wrapper with structured error translation.

### §2.2 EH — ERROR_HANDLING

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

Typed exit codes from `mgf.common.cli._exit_codes` are NOT importable (stdlib-only constraint). Supervisor uses parallel constants in `mgf/test_supervisor/exit_codes.py` pinned to the same values by `test_alignment_with_mgf_common.py`. Structural EH-01 (typed hierarchy) ✅; the implementation diverges from mgf-common's because of TS-23.

### §2.3 LG — LOGGING

(see §3 carve-out — runtime LG-* declined per TS-23)

Output-side rules ✅:
- TestRecord JSONL schema = LG-04 structured-record-shape.
- Deterministic per-test IDs = LG-05 trace-correlation contract.

### §2.4 SC — SECURITY_STANDARD

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

Subprocess management (signal handling, no shell injection, timeout enforcement) ✅. Redaction rules N/A — supervisor reads no secrets; the consumer's test output that the supervisor ingests carries no secrets by TS-22 contract.

### §2.5 CF — CONFIGURATION

(see §3 carve-out — runtime CF-* declined per TS-23)

CLI argparse with structured defaults + a per-project `.gates/` directory for per-run state. No app-runtime settings surface.

### §2.6 AP — API_DESIGN

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

Public surface (`TestRecord`, `MARKER_TIER`, `TIERS`, `effective_tier`, `default_supervisor`) is `__all__`-pinned and alignment-tested against mgf-common's mirror. AP-13 (`__version__` matches pyproject) was the 0.1.3 retro fix; pinned by `test_version_in_sync.py`.

### §2.7 TS — TESTING

(initial audit: ✅ — the supervisor IS the test infrastructure)

The supervisor implements TS-22..TS-27 — that's its reason to exist. The 13-marker taxonomy is in `MARKER_TIER` (PAPER-62 added `integration` + `slow` in v0.1.4). Self-test via `mgf-test-supervisor --self-check`.

### §2.8 DOC — DOCUMENTATION

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

Universal-five present: README, LICENSE, CHANGELOG, this tracker, AGENTS.md. The federation-adoption tracker (MGF_ADOPTION.md) is N/A — this IS the federation test runner, not a consumer.

### §2.9 REL — RELEASING

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

Released in lockstep with mgf-common when alignment-pinned values change (`MARKER_TIER`, `TestRecord` fields). 0.1.4 was the first such cohort-walk (paired with mgf-common 0.41.6 per REL-11).

### §2.10 NAMING

(initial audit: ✅)

Per NM-01..NM-04: PyPI/Codeberg/local-dir = `mgf-test-supervisor` (hyphen); import = `mgf.test_supervisor` (dotted namespace).

### §2.11 AGENTS

(initial audit: ✅)

`AGENTS.md` present; mgf-common's canonical briefing names `mgf-test-supervisor` in `_FEDERATION_SIBLINGS`.

### §2.12 TIME / PERFORMANCE / OBSERVABILITY (v2.8+ additions)

- **TIME** (initial audit: ✅) — wall-clock + monotonic separation honoured; budget timing uses `time.monotonic()`, JSONL `timestamp` field uses `datetime.now(timezone.utc).isoformat()`.
- **PERFORMANCE** (initial audit: ✅) — tier-budget shape closes PAPER-50's "100 µs/record" brittleness via the per-tier wall-clock budget abstraction.
- **OBSERVABILITY** (initial audit: ✅ output side / 🚫 runtime adoption) — see §3.

---

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

| TS-06 | TESTING | Coverage floor 45% (not 80%) | Subprocess-orchestration runner: crash/hang/signal-handling paths execute only against real child processes, so an 80% line floor is disproportionate. Pure-logic core is well-covered (unit+property); orchestration via live-crash/kill-path/self-check. Floor kept at 45% deliberately; revisit if the subprocess paths gain cheaper seams. | 2026-06-07 |

Each 🚫 from §2 listed here with the 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):

- **LG-* runtime adoption (mgf.common.observability) — declined.** Rationale: TS-23 mandates the supervisor stays stdlib-only so it can drive pytest in any consumer's environment without dragging optional deps. Adopting `mgf.common.observability` for the supervisor's own logging would make mgf-common a runtime dependency of every consumer using the supervisor, defeating the dev-only-extras shape. The supervisor instead emits structured JSONL (TestRecord) which is itself the federation logging contract for test outcomes — output-side conformance is preserved.

- **CF-* MgfSettings adoption — declined.** Same TS-23 rationale. The supervisor takes CLI arguments + a per-project `.gates/` state directory; no app-runtime configuration is needed. Settings-shaped concerns (budget knapsack, tier thresholds) are exposed via CLI flags + `pyproject.toml [tool.mgf-test-supervisor]` reads via stdlib `tomllib`.

- **OB-* runtime adoption — declined.** Same TS-23 rationale. The supervisor's observability surface IS the TestRecord JSONL output, which downstream consumers (CI dashboards, federation roll-ups) ingest. No OTel emission from the supervisor itself.

If/when TS-23 is revisited (it has not been since the supervisor extracted from in-tree `scripts/_mtest/`), these declines also revisit.

---

## §4 Audit log

(One row per audit pass. Drift over time is the signal.)

| Date | Auditor | Trigger | Findings |
|---|---|---|---|
| 2026-05-27 | initial audit (federation L2-floor pass) | mgf-common federation tracker showed mgf-test-supervisor had no conformance doc; sibling-wide walk-up to L2 minimum | scaffolded; 3 declines documented (LG / CF / OB runtime, all driven by TS-23); first depth audit to follow on next standards bump |
| 2026-06-07 | depth audit (16-family fan-out + adversarial refute; ~43 agents/2 runs + 9-id micro-audit) | first evidence-based per-MUST audit | **62 ✅ / 51 ⏳ / 105 N/A** of 218; declared level corrected L2→below-L2 (prior 'green by construction' estimate falsified). Clusters: TESTING self-conformance (~21), CI publish pipeline (WF-02..08/REL-06/08), API surface (AP-01/02/05/08/10/11/14), SCOPE (SP-01..06). Audit only — no code changed. |

---

## §5 Cross-references

- [`mgf-standard/docs/standards/`](https://codeberg.org/magogi-admin/mgf-standard/src/branch/main/docs/standards/) — the standards source-of-truth.
- [`mgf-standard/docs/standards/TESTING.md`](https://codeberg.org/magogi-admin/mgf-standard/src/branch/main/docs/standards/TESTING.md) §19 — the home standard for this library (TS-22..TS-27).
- [`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) — CFM-04 documented-non-adoption principle.
- [`tests/unit/test_alignment_with_mgf_common.py`](../../tests/unit/test_alignment_with_mgf_common.py) — alignment-pin between this sibling's public surface and mgf-common's mirror. The structural enforcement that backs the ✅ marks above.

---

---

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

> **2026-06-07 depth audit** (16-family fan-out + adversarial refute on every ✅; ~43 agents over 2 runs + a targeted micro-audit; the first run's TESTING/PR auditors echoed this scaffold and 6 big families truncated — caught by a completeness check and re-run with a hardened no-scaffold prompt). Each ✅ cites file:line and survived refutation. **Mix: 62 ✅ · 51 ⏳ · 105 N/A · 0 🚫** (4 auditor-🚫 reclassified ⏳ — they were unmet, not CFM-04 declines). Replaces the prior all-⏳ scaffold.


### DESIGN_PRINCIPLES

| Rule | Status | Evidence | Notes |
|---|---|---|---|
| DP-01 | ✅ | grep for PySide/PyQt/tkinter/requests/httpx/click/pydantic/numpy/pandas across src/ → NONE FOUND. The only non-stdlib import is a lazy, try/except-guarded `import mgf.common` at diagnostics. | Refute attempt: the literal MUST is 'Layering MUST be enforced; UI MUST NOT be imported by core; core MUST NOT import third-party SDKs that have a provider in front of them; CI lints this.' The only refutable hook is the absent lint-imports |
| DP-02 | N/A | Stdlib-only by mandate (TS-23): the supervisor never imports a third-party I/O SDK at runtime — grep for SDK imports across src/ returns NONE. pytest is driven as an out-of-process subproces | Not in the ✅ challenge set. DP-02 mandates provider ABCs for third-party I/O dependencies. Per the TS-23 carve-out this project has no runtime third-party I/O surface — it shells out to pytest as a subprocess. N/A by carve-out; unchanged. |
| DP-03 | ✅ | The two domain types that cross module boundaries as identity are frozen: records.TestRecord (records.py:54 `@dataclass(frozen=True, slots=True)`, written to JSONL and passed supervisor→reco | Refute attempt: the MUST is 'Domain types passed between modules MUST be frozen; bare strings/dicts MUST NOT cross a module boundary as identity.' I checked every non-frozen dataclass for an identity-crossing role and found none: RunConfig/ |
| DP-04 | ✅ | Re-ran `.venv/bin/python -m mypy --strict src/` → 'Success: no issues found in 11 source files'. pyproject.toml:159-174 sets strict=true, disallow_untyped_defs, disallow_incomplete_defs, war | Refute attempt: the MUST is 'every public function MUST be type-annotated; mypy --strict MUST pass on src/; no Any without a justification comment.' mypy --strict passes clean (re-verified) and is a CI gate. The only refutable point is the  |
| DP-05 | N/A | Not in the ✅ challenge set (testability is its own TESTING family). The project tests itself via self_check.py + a tests/ suite; the carve-out notes the supervisor both IS the tooling and ha | DP-05 (tests mirror src 1:1, no real I/O) was not provided as a ✅ to challenge in this DESIGN_PRINCIPLES refute pass; it is a TESTING-family concern. Not assessed here as a ✅; unchanged. |
| DP-06 | N/A | Not in the ✅ challenge set. DP-06 (security/reliability/performance/error-reporting first-class in every PR) is a process/review checklist rule, not a source-level invariant supplied as a ✅  | DP-06 was not provided as a ✅ verdict to challenge; it is a PR-description discipline rule outside the source-derived set given. Not assessed here as a ✅; unchanged. |
| DP-07 | ✅ | Why-focused module docstrings on every module (supervisor.py:1-36 'why outside pytest'; records.py:1-16; diagnostics.py:1-39; tiers.py:1-20; perf.py:1-24; quarantine.py:1-21; selection.py:1- | Refute attempt: the MUST is 'every public class/function MUST have a docstring explaining intent and invariants; what-comments forbidden.' I hunted for missing docstrings and what-comments. Coverage is strong and the docstrings genuinely ex |
| DP-08 | N/A | Not in the ✅ challenge set. DP-08 (replaceability swap-recipe docs near each abstraction) presupposes major swappable external dependencies (UI toolkit/hypervisor/DB); per the TS-23 stdlib-o | DP-08 was not provided as a ✅ verdict to challenge; and with no provider-fronted external dependency (TS-23) the swap-recipe table has no rows to mandate. Not assessed here as a ✅; unchanged. |
| DP-09 | N/A | Not in the ✅ challenge set. Cancellation here is signal-driven (supervisor.py:116-117 wires SIGINT/SIGTERM to a flush-and-exit handler) + subprocess SIGTERM→SIGKILL escalation (supervisor.py | DP-09 (explicit CancellationToken on long-running ops) was not provided as a ✅ verdict to challenge in this pass. The cancellation model is process-signal-based (appropriate for a subprocess supervisor), not the token-threaded shape DP-09 t |
| DP-10 | ✅ | Fallbacks are queryable/surfaced, not silent: (1) pytest-cmd resolution prefers the consumer's .venv python, falls back to sys.executable (__main__._find_pytest_cmd:72-78), and the chosen ar | Refute attempt: the MUST is 'If a fallback path exists, the active backend MUST be queryable and SHOULD be logged at startup.' The keyring→encrypted-file worked example doesn't apply (no secrets handled), but the principle binds to the fall |
| DP-11 | N/A | Not in the ✅ challenge set, and not applicable on the merits: grep for asyncio/create_task/async def/await across src/ → 'NO ASYNC'. The supervisor is fully synchronous (subprocess + signals | DP-11 (async task ownership) was not provided as a ✅ verdict to challenge, and there is no async code in the project, so the rule binds nothing here. N/A on the merits; unchanged. |
| DP-12 | ✅ | All timestamps UTC with explicit Z: records.now_iso() (records.py:123-128) builds the ISO-8601 string from time.gmtime() (UTC) and appends a literal 'Z' (line 127); durations._now_iso() (dur | Refute attempt: the MUST (governed by TIME.md) is 'Time MUST be UTC at every boundary; naive datetimes MUST NOT cross a module boundary; serialised form is ISO-8601 with explicit Z/+00:00.' Every emitted timestamp is gmtime-derived UTC with |
| DP-13 | ✅ | Every owned resource released deterministically. Files: `with path.open(...)` (records.py:178 read_jsonl, quarantine.py via fdopen, supervisor._write_state:519 os.fdopen-in-with); the one ra | Refute attempt: the MUST is 'every owned external resource MUST be acquired inside a with or paired with try/finally; reliance on GC is a defect.' I traced every file/subprocess/lock/temp-fd in src/: all are context-managed or explicit try/ |

### ERROR_HANDLING

| Rule | Status | Evidence | Notes |
|---|---|---|---|
| EH-01 | N/A | No `exceptions.py` / project base error class exists in src/mgf/test_supervisor/ (no AppError hierarchy). Application code raises only stdlib exceptions: ValueError (records.py:95/97, tiers. | EH-01 (every raised exception MUST subclass the project base AppError) presumes a typed application-exception hierarchy from a runtime mgf-common surface. Under the stdlib-only mandate (TS-23) this tool has no AppError to subclass; it is an |
| EH-02 | N/A | Third-party/SDK boundaries are not present at runtime: the only external calls are subprocess (pytest as a child process) and stdlib filesystem/json. subprocess errors are handled by returni | EH-02 (translate third-party exceptions to typed AppError subclasses at the owning boundary) presumes a provider/SDK/HTTP/DB driver surface and a runtime AppError hierarchy. This stdlib-only supervisor has neither — its 'boundary' converts  |
| EH-03 | ✅ | Full-codebase grep for raise-with-from: only __main__.py:104 `) from None` (translating the flock OSError caught at :99 into a SystemExit). No other site re-raises a caught exception. Every  | EH-03 binds when a TRANSLATED exception is re-raised. The single such site (__main__.py:100-104, inside `except OSError`) uses explicit `from None`. The standard's §11.5 lists `raise OperationError(...) from None` as a RIGHT shape (owner-co |
| EH-04 | ✅ | Entry point is argparse `main()` at __main__.py:143, wired via pyproject [project.scripts] (mgf-test-supervisor/mtest). `main` returns int for every path; per-category mapping present: Value | Carve-out: CF/Click is N/A (argparse CLI, no MgfSettings), so the Click-specific `_run_and_translate_exceptions`/`cli_main` indirection in §4.1 does not bind; the equivalent int-returning top-level with documented exit-code mapping is prese |
| EH-05 | N/A | No crash reporter (no report_now / install_excepthook); `mgf.common.observability` is unavailable at runtime by the TS-23 stdlib-only mandate. Unhandled exceptions are not the model here — t | EH-05 (unhandled exceptions produce a local JSON crash report + optional remote sink) depends on the runtime `mgf.common.observability` crash reporter, which is excluded by the stdlib-only/DEV-only carve-out. The tool's analogue — structure |
| EH-06 | N/A | No GUI: argparse CLI only, no Qt/QThread/worker layer anywhere in src/. (PR carve-out confirms no GUI framework.) | EH-06 governs GUI worker threads (catch every exception, forward via error(str) signal, route untyped through crash reporter). There is no GUI and no worker layer, so the rule has no surface to bind to. Not part of the 5 challenged ✅; uncha |
| EH-07 | ✅ | Full grep of every `except` clause: exactly two `except Exception:` — (1) supervisor.py:127 in _on_signal, a SIGINT/SIGTERM flush/cleanup path that prints to stderr then sys.exit() (:128-129 | EH-07 permits `except Exception:` only in (a) cleanup paths and (b) best-effort observer loops that log+continue with a documented invariant. Site (1) is a cleanup/flush path that logs+exits (case a). Site (2) is a test-harness best-effort  |
| EH-08 | N/A | No typed application exceptions are defined or raised (see EH-01). The only raised exceptions are stdlib ValueError/SystemExit carrying message strings; there is no project exception class t | EH-08 (every typed exception carries machine-readable fields, not just a message) presumes a typed AppError hierarchy, which this stdlib-only tool does not have. The machine-readable surface is the TestRecord/JSONL data model, not exception |
| EH-09 | ✅ | User-facing CLI strings carry actionable next steps: __main__.py:66-69 ('cd into your project directory ... or set MGF_TEST_SUPERVISOR_REPO_ROOT=/path/to/project.'); :262-263 ('Is the venv i | EH-09's MUST is that user-shown messages end in an actionable step where possible; the CLI surface consistently does (install command, env-var escape hatch, flag to set, conflicting-run resolution). The §9 dedicated substring-pinning test f |
| EH-10 | ✅ | diagnostics.py module docstring (lines 1-11) states every function returns a str and NEVER raises; `_safe_run` (82-99) catches FileNotFoundError/TimeoutExpired/OSError and returns '(command  | EH-10's never-raises observer shape (catch broadly, surface context, continue) is realized: the diagnostics module and _signal_group both document the never-raises invariant in docstrings and return strings/None on failure rather than propa |
| EH-11 | N/A | No retry loop against any external system exists. The supervisor runs each pytest chunk exactly once; on timeout it escalates SIGTERM->grace->SIGKILL (supervisor.py kill path) and records th | EH-11 (retries MUST use exponential backoff + full jitter + finite cap) binds only where the code retries an external call. There is no such retry surface — pytest chunks run once and failures become recorded outcomes. Rule does not bind. N |
| EH-12 | N/A | No multi-attempt writes/sends against an external system. State writes are local-filesystem and already atomic (state.json atomic write; run.jsonl append-only; the _gates_lock flock at __mai | EH-12 (operations with multi-attempt cost MUST be idempotent, keyed on a natural key) binds to external writes/sends. The tool's only writes are local, atomic, and lock-serialised; no external multi-attempt operation exists. Rule does not b |
| EH-13 | N/A | No external upstream that failing retries could amplify. The supervisor's only 'external' callee is a local pytest child process it spawns once per chunk; there is no shared/overloadable ups | EH-13 (upstream-amplifying load MUST be bounded; circuit breaker canonical) binds to external calls that can worsen a struggling upstream. There is no such upstream — pytest is a local single-shot child process. Load is structurally bounded |

### LOGGING

| Rule | Status | Evidence | Notes |
|---|---|---|---|
| LG-01 | N/A | grep for 'getLogger\|import logging\|logging.' over src/mgf/test_supervisor/*.py returns zero matches (Bash, exit 1, no output). The project uses no Python logging module at all; all human o | LG-01's premise is a logging-module pipeline ('acquire its logger via logging.getLogger(__name__)'). This stdlib-only CLI test supervisor (TS-23) deliberately has no logging pipeline — per the audit carve-out 'OBSERVABILITY/LOGGING: output- |
| LG-02 | N/A | No setup_logging / logging.basicConfig anywhere in src (grep zero matches). Entry point src/mgf/test_supervisor/__main__.py uses argparse + print(); there is no logging configuration point a | LG-02 requires configuring the logging module at the entry point and emitting JSON logs when stdout is not a TTY. The project has no logging pipeline to configure (TS-23 stdlib-only carve-out). The JSONL TestRecord stream is a data artifact |
| LG-03 | N/A | No logging records exist and no OpenTelemetry import in src (grep for 'opentelemetry\|trace_id\|span_id' would match nothing; the only correlation IDs are deterministic per-test IDs). OTel c | LG-03 binds log records carried through the standard formatter with OTel trace/span context. There are no log records and no tracing pipeline. Premise does not bind under the stdlib-only carve-out. |
| LG-04 | N/A | No Redactor / formatter / logging sink in src (grep zero matches for logging). Redactor lives in mgf.common.observability (LOGGING.md note line 7), which is a dev-only dep never imported at  | LG-04 requires the formatter to redact sensitive fields before any sink sees them. There is no formatter and no sink (no logging pipeline). Premise does not bind (TS-23 carve-out). |
| LG-05 | N/A | No LOG.exception / exc_info usage because there is no logger (grep zero matches). Error reporting to humans is via print(f"mtest: {e}", file=sys.stderr) (__main__.py:250; supervisor.py:128,4 | LG-05 mandates ERROR-level LOG records include the exception via exc_info. The project emits no log records — failures surface either as CLI stderr messages or as failure bundles/JSONL fields. The rule's premise (an ERROR log record) does n |
| LG-06 | N/A | The project ships no operator log aggregator because it produces no logs. It does emit a structured, searchable JSONL run-record file (records.py append-only os.write at line 155-160) and hu | LG-06 ('logs MUST reach a searchable aggregator; console-only in production is non-compliant') presupposes a logging pipeline and a production deployment. This is a stdlib-only dev/CLI tool with no logging stream and no production service s |
| LG-07 | N/A | Applies-to is 'gui-app' (LOGGING.md line 21/44). No GUI in this project: grep for 'pyside\|qt\|tkinter\|gui\|app.run' over src/ and pyproject.toml returns zero matches. The audit carve-out s | LG-07 binds only GUI desktop apps (log-viewer dialog reading the rotating file). This is a headless CLI tool with no GUI surface. Premise does not bind. |
| LG-08 | N/A | LG-08 requires LOG.* calls use lazy %-formatting not f-strings. There are no LOG.* calls (grep zero matches for logging). The codebase does use f-strings, but only inside print() CLI output  | LG-08's MUST is scoped to log message emission through the logging level filter. With no logging module in use, there is no level-gated message template to keep lazy. Premise does not bind (TS-23 carve-out). |
| LG-09 | N/A | LG-09 governs passing structured fields via extra={...} to the logging module so the JSON formatter promotes them. No logging / extra= usage in src (grep zero matches). The project's structu | LG-09's premise is the logging-module extra={}→JSON-key promotion path, which does not exist here (stdlib-only carve-out). The output-side structured-record requirement is met by the JSONL schema, but the LG-09 mechanism does not bind. Prem |
| LG-10 | N/A | Applies-to is 'service' (LOGGING.md line 24/45). No service/daemon/systemd entry: grep for 'systemd\|journal\|JournalHandler\|app.run' over src/ + pyproject.toml returns zero matches. The on | LG-10 binds headless services (systemd timers/daemons) requiring a JournalHandler sink. This is a CLI library/tool, not a long-running service (DEP carve-out). There is no service entry point and no logging pipeline to add a journald sink t |
| LG-11 | N/A | LG-11 requires operation start/end LOG.info records with a stable 'operation' field. No logging records exist (grep zero). Operation/duration data is captured structurally in the TestRecord/ | LG-11's MUST is expressed as INFO log records carrying an 'operation' field so flows are reconstructable from logs. With no logging pipeline (TS-23 carve-out), there are no such records; flow reconstruction is served instead by the JSONL ru |
| LG-12 | N/A | LG-12 ('log emission MUST be ≤100µs; heavy formatting/IO in the handler not the call site') presupposes logging handlers and a call-site/handler split. No logging module is used (grep zero m | The rule's premise — a logging emission path with handlers — does not exist in this stdlib-only tool. Premise does not bind (TS-23 carve-out). |
| LG-13 | N/A | LG-13 ('high-frequency log sites MUST rate-limit/sample so a runaway condition does not flood sinks'; canonical shapes in §15) presupposes log sites and sinks. None exist (no logging module; | With no logging sinks, there is nothing to flood and no rate-limiting/sampling mechanism to require. Premise does not bind (TS-23 stdlib-only carve-out). |
| LG-14 | N/A | LG-14 ('correlation context MUST propagate via contextvars.ContextVar; the standard formatter promotes registered contextvars to log fields') presupposes the standard logging formatter and l | The premise is contextvar-to-log-field promotion through the standard formatter, which does not exist without a logging pipeline (TS-23 carve-out). Premise does not bind. |
| LG-15 | N/A | LG-15 requires every INFO+ log record at notable lifecycle/security/boundary events to carry a stable 'event' field documented in docs/reference/EVENTS.md. No logging records exist (grep zer | LG-15's MUST is scoped to INFO+ log records and their event-field registry. With no logging pipeline (TS-23 carve-out), there are no such records to tag and no alert-target log events. Premise does not bind. |
| LG-16 | N/A | LG-16 ('every WARNING and ERROR record MUST answer WHAT/WHY/HOW, WHY via extra={} fields') is explicitly scoped to log records ('This is why LG-16 is a MUST at WARNING+ specifically', LOGGIN | The rule's premise is WARNING/ERROR records emitted through the logging module with extra={} context. This stdlib-only tool emits no log records (TS-23 carve-out); WHY-as-extra-fields cannot apply to print() lines. Premise does not bind und |
| LG-17 | N/A | LG-17 ('every ERROR record SHOULD carry a stable fingerprint ... the formatter computes this automatically when exc_info is set') is itself a SHOULD (LOGGING.md:458 'LG-17 is a SHOULD (not a | Premise does not bind: there is no logging pipeline producing ERROR records and no grouping backend in scope — exactly the carve-out LG-17 itself names ('many ERROR sites don't ship to a grouping aggregator ... carve out only when you've ve |

### CONFIGURATION

| Rule | Status | Evidence | Notes |
|---|---|---|---|
| CF-01 | N/A | pyproject.toml:46 `dependencies = []` (stdlib-only, TS-23); `grep pydantic\|BaseSettings\|MgfSettings src/` → no matches; src/mgf/test_supervisor/__main__.py:26 uses `argparse` only. No pyda | CF-01 'Applies to: consumer-owned-config' — premise is a consumer that owns a pydantic-settings config schema. This project owns none: it is stdlib-only by TS-23 mandate (no runtime mgf-common, no pydantic). The carve-out (CF=N/A, no MgfSet |
| CF-02 | N/A | There is no layered config-source loader: no pydantic Settings, no .env handling, no on-disk YAML config file read anywhere in src/. CLI is argparse (__main__.py:166 `_build_parser`); env es | Although CF-02 'Applies to: all', its substance (CLI flags > env > .env > on-disk config file > typed defaults precedence) presupposes a multi-source config object to merge. This project has no config file, no .env support, and no typed-def |
| CF-03 | N/A | No config schema exists (no pydantic Settings; pyproject.toml:46 zero runtime deps). No `version` field on any settings object; no migration chain. The JSONL TestRecord output schema is an e | CF-03 'Applies to: consumer-owned-config'. The premise — a loadable config schema that can carry a `version` field and run migrations — does not exist. There is no on-disk app config to version. N/A by the stdlib-only/no-MgfSettings carve-o |
| CF-04 | N/A | No config file is written by the app. The supervisor writes JSONL run records / quarantine / perf state under `.gates/` (records.py, quarantine.py, perf.py), but there is no `config.yaml` sa | CF-04 'Applies to: consumer-owned-config' and governs atomic writes/0o600/lazy path-expansion of THE CONFIG FILE. This project has no consumer-owned config file to write atomically. The premise does not bind. (State-file atomicity for .gate |
| CF-05 | N/A | No config file exists and no secrets are stored. The only env reads are MGF_TEST_SUPERVISOR_REPO_ROOT (__main__.py:58, a path) and MGF_TEST_SUPERVISOR_DAEMON_PROCESS_NAME (diagnostics.py:76, | CF-05 'Applies to: all' but its premise is a project that handles secrets (which must then go to a Vault, not config). This test supervisor neither stores nor reads any secret and has no config file in which a secret could leak. With no sec |
| CF-06 | N/A | No config-file loader exists (no pydantic `extra="forbid"`, no YAML config read). pyproject.toml:46 zero runtime deps; grep for pydantic → none. | CF-06 'Applies to: consumer-owned-config' — unknown-key rejection on loading the config file. There is no config file and no schema loader, so there are no keys to accept or reject. Premise does not bind (stdlib-only carve-out). |
| CF-07 | N/A | No main `Settings` config exists, hence no satellite sub-config files following its shape. The `.gates/` artifacts (run records JSONL, quarantine, perf) are emit-side run state, not typed py | CF-07 'Applies to: consumer-owned-config' and requires sub-config files to mirror the main typed-config shape. With no main consumer-owned config schema (carve-out: no MgfSettings/pydantic per TS-23), there is no parent shape for satellites |
| CF-08 | N/A | No `Settings` object exists to load-once-and-inject (no pydantic; pyproject.toml:46). The entry point __main__.py builds an argparse Namespace + a RunConfig dataclass (supervisor.py `RunConf | CF-08 'Applies to: consumer-owned-config' — load the Settings object once and pass via constructor injection, no module-global singleton. The premise (a Settings object) does not exist under the stdlib-only/no-MgfSettings carve-out. N/A. |
| CF-09 | N/A | `_build_parser` (__main__.py:166-235) defines flags (--version, --verbose, subcommand, etc.) but no `--config <path>` flag, and no XDG/OS default config path resolution — because there is no | CF-09 'Applies to: consumer-owned-config' — a `--config <path>` flag pointing at the on-disk config with XDG/OS defaults. This project has no on-disk config file to point at; a `--config` flag would reference nothing. Premise does not bind  |
| CF-10 | N/A | No `Settings` class exists to construct with explicit values in tests (no pydantic; pyproject.toml:46). Tests in tests/unit and tests/smoke exercise the supervisor's modules directly; there  | CF-10 'Applies to: all', but its premise is the existence of a `Settings` class that tests must instantiate with explicit overrides (`Settings(**overrides)` / `model_construct`) to avoid env leakage. No such class exists in this stdlib-only |
| CF-11 | N/A | No pydantic config schema and no `Field(alias=...)`/`validation_alias` machinery exists (no pydantic; pyproject.toml:46). There are no on-disk config fields that could be renamed-with-back-c | CF-11 'Applies to: consumer-owned-config' — renaming a config field via pydantic alias to keep old on-disk configs loading. With no config schema and no on-disk config (stdlib-only carve-out), there is no field to rename and no legacy confi |
| CF-12 | N/A | No config field has mutually-exclusive backend variants. There is no vault/cache/queue backend selection in the project; no pydantic discriminated union machinery exists (no pydantic; pyproj | CF-12 'Applies to: all' but is conditional ('When a config field has multiple mutually-exclusive backend variants ... they MUST be modelled as a discriminated union'). This project has no such multi-variant backend config field, so the cond |

### SECURITY_STANDARD

| Rule | Status | Evidence | Notes |
|---|---|---|---|
| SC-01 | ✅ | .woodpecker.yml:74-77 secret-scan step runs gitleaks v8.30.1 `detect --source . --no-banner --redact` (working tree + history) on push/PR/manual, no failure suppression. grep over src/ for m | SC-01 forbids secrets in config/source/logs and (§2.3/§15 matrix) mandates a CI secret scanner on every PR. The project stores none of its own secrets and runs gitleaks as a hard PR gate. Tried to refute: no committed .env, no embedded keys |
| SC-02 | ✅ | grep `shell=True` over src/ → NONE. All call sites use argv lists with shell=False (default): supervisor.py:237 Popen(argv,…), :706 & :755 run(argv,…), diagnostics.py:86 run(argv,…). argv at | SC-02 requires argv + shell=False and forbids shell=True / f-string templates into a shell. Tried to refute by hunting for any string-built command or os.system: none exist. No user-template→shell path. Upheld. [verify-upheld] |
| SC-03 | ✅ | grep `yaml` over src/ → NONE; grep `pickle` → NONE. JSON read via json.loads at durations.py:45, __main__.py:424, perf.py:57, records.py:184, quarantine.py:86, diagnostics.py:219. Only XML i | SC-03 forbids yaml.load (absent — no yaml at all), forbids pickle (absent), mandates json.loads for JSON (satisfied). §4.4 recommends defusedxml for XML; here the XML is application-controlled (a file the supervisor wrote itself to a path i |
| SC-04 | ✅ | Not in the challenged-✅ set. SECURITY.md §Scope names 'atomic state writes under .gates/' and 'the diagnostic-bundle environment fingerprint (must not leak secrets into a .txt)' as in-scope, | SC-04 mandates 0o600 + atomic writes for files that may contain private data. The challenge list did not include SC-04 as an upheld ✅, and this pass focused on the 10 listed claims. The supervisor writes .gates/ state, durations, quarantine — VERIFIED 2026-06-07: .gates state files are 0o600 (tempfile.mkstemp default, preserved through atomic replace) — pinned by tests/unit/test_state_file_security.py |
| SC-05 | N/A | grep -E `md5\|sha1\|random\.` over src/ → NONE. No cryptographic primitives anywhere in src/mgf/test_supervisor/. dependencies=[] (pyproject.toml:46); stdlib-only runtime. No tokens, nonces, | SC-05 governs choice of crypto primitives. The supervisor performs no cryptography, generates no tokens/keys/nonces, and uses no random source for security. There is no surface the rule applies to. N/A (carve-out: stdlib-only test tool with |
| SC-06 | N/A | grep `verify=False\|CERT_NONE\|AutoAddPolicy` over src/ → NONE. No httpx/requests/paramiko/ssl usage; dependencies=[] runtime. The supervisor makes no outbound network/TLS/SSH connections —  | SC-06 governs TLS verification on outbound connections. The supervisor has no outbound network surface — no HTTP, SSH, or TLS client. The rule has no applicable call site. N/A (carve-out: no network surface). |
| SC-07 | ✅ | Every subprocess boundary carries a finite timeout. Popen path: communicate(timeout=chunk_budget) then a bounded SIGTERM→communicate(timeout=SIGTERM_GRACE_S)→SIGKILL→communicate(timeout=5.0) | SC-07 mandates a finite timeout on every external call; subprocess is the named surface. Tried to refute by finding a blocks-forever path: even the post-SIGKILL communicate is bounded (timeout=5.0) with a no-block fallback, so there is no i |
| SC-08 | ✅ | Boundary validation present: tiers.parse_tier_range range-checks `not (0 <= lo <= hi <= 3)` and raises ValueError (tiers.py:137-141); _parse_budget defensively parses s/m/h suffixes returnin | SC-08 requires validation at the parser boundary before use-case code. The argparse CLI range-checks tiers, parses budget, and the record/parser layer allow-lists categorical fields and tolerates malformed serialized input. Per the CF/argpa |
| SC-09 | N/A | No runtime logging pipeline / log formatter / Redactor in src/. Per the audit carve-out, LOGGING/observability is output-side-only: the supervisor emits structured JSONL run records (records | SC-09 requires a formatter-level Redactor before any log sink. The supervisor has no logging pipeline / sink to redact at — it serializes operator-owned test outcomes to JSONL and stderr. There is no secret-bearing log-record surface the ru |
| SC-10 | ✅ | uv.lock is git-tracked (`git ls-files uv.lock` → uv.lock) and present (156 KB). CI vuln scan: .woodpecker.yml:65-71 vuln-scan step on python:3.12-slim runs `pip-audit --strict` on every push | SC-10's literal MUSTs are (a) a committed lockfile and (b) a CI vuln scanner on every PR — both satisfied (uv.lock committed; pip-audit --strict as a hard PR gate). Tried to refute on the scan-target gap: the rule requires 'CI MUST run a vu |
| SC-11 | ✅ | No secrets exist in scope (stdlib-only, no vault). Exception/error messages surface only command names, pids, paths, exit codes, and pytest-controlled text: supervisor.py:128 `signal handler | SC-11 forbids tracebacks/crash reports leaking secret material. The supervisor owns no secrets, and its diagnostic bundle deliberately emits a curated fingerprint rather than an env-var dump. Tried hard to refute: searched for an os.environ |
| SC-12 | ✅ | SECURITY.md exists at repo root (5246 bytes) with: Supported versions table (lines 20-22, `0.1.x` ✅); private reporting channel (lines 33-39: email bassam@magogi.org + Codeberg private secur | SC-12 requires a root SECURITY.md with supported versions, security contact, embargo, and disclosure timeline. All four are present and substantive (matches the §11.1 template, customised to this project). Tried to refute: each required ele |
| SC-13 | N/A | No cryptographic keys anywhere; grep for `md5\|sha1\|random.` → NONE, no crypto imports, no embedded key literals. dependencies=[] runtime; stdlib-only. | SC-13 governs at-rest key derivation/storage. The supervisor has no keys at rest, no KDF surface, and embeds no key material. The rule has no applicable surface. N/A (carve-out: no crypto/key surface). |
| SC-14 | N/A | No authentication surface in src/. The supervisor is an argparse CLI that spawns local pytest subprocesses; it authenticates no person or service and has no login/credential-check path. | SC-14 governs authentication-failure non-enumeration and rate-limiting. The supervisor performs no authentication. There is no auth boundary the rule attaches to. N/A. |
| SC-15 | ✅ | Not in the challenged-✅ set. Paths handled include the run dir under .gates/, junit-<N>.xml (supervisor.py:208), durations/quarantine/state files, and /proc/<pid>/* reads in diagnostics (bui | SC-15 mandates traversal validation on paths built from external input. The supervisor's path inputs are operator-supplied CLI args (repo_root, run dir) and pytest-controlled node-ids/XML filenames it generates itself — low external-travers — VERIFIED 2026-06-07: _safe_filename strips every path separator (re.sub [^A-Za-z0-9._-]→_) so a traversal-shaped test_id collapses to a flat basename — pinned by test_safe_filename_strips_path_separators |
| SC-16 | N/A | grep over src/ for sudo/setuid/privileged/capability → none. The supervisor runs as the invoking user, spawns pytest in a new session/group (start_new_session=True, supervisor.py:250) only t | SC-16 governs privileged-operation confinement (sudo/setuid/capabilities). The supervisor performs no privilege escalation; start_new_session is process-group management, not privilege. No privileged surface to confine. N/A. |
| SC-17 | N/A | No runtime audit-log pipeline (no logging framework / INFO sink in src/, per the output-side-only carve-out). The security-relevant actions SC-17 enumerates (vault read/write, SSH connect, c | SC-17 requires audit=true INFO records for security-relevant actions. The supervisor has no logging pipeline and none of the enumerated security-relevant actions (no vault/SSH/auth/config-write/key-rotation). The one named surface — 'subpro |
| SC-18 | ✅ | pyproject.toml [build-system] requires=['hatchling>=1.21'], build-backend='hatchling.build' (lines 84-86), deterministic packages=['src/mgf'] (line 91); runtime dependencies=[] (line 46) so  | SC-18 requires the artefact be buildable from a tagged commit using only declared dependencies; build metadata is required only for binary-wheel projects. hatchling + empty runtime deps + committed lockfile + pure-Python (py3-none-any) whee |

### TESTING

| Rule | Status | Evidence | Notes |
|---|---|---|---|
| TS-01 | ✅ | tests/unit/ does NOT mirror src/ 1:1. src has 11 runtime modules (supervisor, selection, tiers, quarantine, records, durations, perf, diagnostics, self_check, __main__, __init__). tests/unit | Mirror layout absent and no CI mirror-check/allow-list; selection.py and durations.py have no direct mirror file. — FIXED 2026-06-07: tests/test_mirror.py (searches unit/+smoke/) + MIRROR_ALLOWLIST.txt documenting each non-1:1-named module's covering test |
| TS-02 | ✅ | pyproject dependencies=[] (line 46); unit tests use tmp_path + monkeypatched subprocess.Popen (test_kill_path), synthesized JSONL (test_self_check_visibility), and local pytest subprocesses  | No real-I/O/creds/network/daemon in the unit suite; MockProvider clause vacuous because there is no third-party I/O ABC surface. Refutation attempt found no counterexample. — RECONCILED 2026-06-07: status corrected ⏳→✅; the depth-audit refute pass flipped the label but its own evidence is upheld ("canonical reference / no counterexample / verify-upheld / vacuously met"). Re-read confirms MET. |
| TS-03 | ✅ | REFUTED. Supervisor.__init__ installs PROCESS-GLOBAL signal handlers as a construction side effect — supervisor.py:116-117 `signal.signal(signal.SIGINT, self._on_signal)` / `signal.signal(si | In-process Supervisor construction leaks unrestored process-global signal handlers; no fixture saves/restores them. Counterexample found, claim refuted. — FIXED 2026-06-07: tests/conftest.py autouse fixture saves/restores SIGINT/SIGTERM around every test (Supervisor.__init__ installs them as a side effect) |
| TS-04 | ✅ | pyproject.toml [tool.pytest.ini_options] filterwarnings = ["error"] (lines 201-203). Literal MUST satisfied — warnings escalate to errors. [verify-upheld] | Exact config line present; no counterexample (no broad per-file ignore of filterwarnings found). — RECONCILED 2026-06-07: status corrected ⏳→✅; the depth-audit refute pass flipped the label but its own evidence is upheld ("canonical reference / no counterexample / verify-upheld / vacuously met"). Re-read confirms MET. |
| TS-05 | ✅ | pyproject.toml addopts includes "--strict-markers" (line 188) and "--strict-config" (line 189). Both MUST flags set. [verify-upheld] | Both flags literally present in addopts. — RECONCILED 2026-06-07: status corrected ⏳→✅; the depth-audit refute pass flipped the label but its own evidence is upheld ("canonical reference / no counterexample / verify-upheld / vacuously met"). Re-read confirms MET. |
| TS-06 | 🚫 | TS-06 MUST: coverage gate ≥80% on every CI job, ≥90% on changed lines in a PR. pyproject [tool.coverage.report] fail_under = 45 (line 233) — well below the 80% MUST. .woodpecker.yml runs --c | Coverage floor 45% is below the 80% MUST and there is no per-PR changed-lines ≥90% gate. — DECLINED 2026-06-07 (CFM-04): an 80% line-coverage floor is disproportionate for a subprocess-orchestration runner whose crash/hang/signal paths only execute against real child processes; the deliberate floor is 45%. The pure-logic core (records/tiers/selection/quarantine/perf) is well-covered by unit+property tests; the orchestration paths by the live-crash/kill-path/self-check tests. See §3. |
| TS-07 | N/A | The supervisor defines no typed-exception hierarchy of its own (records.py raises bare ValueError on unknown outcome/severity; no custom exception classes with copied fields). It is a stdlib | No typed exception surface exists to test; rule has no applicable target here. |
| TS-08 | N/A | No EH-02 translation seams (third-party error → typed domain error) exist — the supervisor has no third-party I/O surface (stdlib-only, dependencies=[]). diagnostics probes (pgrep/dmesg) and | No translation-seam surface; carve-out (no third-party I/O ABCs) makes this rule inapplicable. |
| TS-09 | N/A | No EH-10 'best-effort observer' loop pattern (a registered observer list iterated with per-observer try/except) is present in the runtime. The fail-open patterns are per-artifact file reads  | No raising-observer loop seam to inject into; rule's specific construct is absent. |
| TS-10 | N/A | Per the audit carve-outs, CF/observability/security-runtime surfaces are N/A for this stdlib-only argparse tool. There is no SC-01..SC-18 runtime surface (no YAML loader, no shell=True path  | No applicable SC-rule runtime surface to pin; security scanning is CI-side, not a TS-10 pin-test target. |
| TS-11 | N/A | Per the audit carve-out: no GUI / PySide6 / QThread workers exist anywhere in src/. The supervisor is a CLI. TS-11 (GUI worker success + untyped-exception path) has no target. | No GUI workers; rule inapplicable. |
| TS-12 | N/A | pyproject sets asyncio_mode="strict" and asyncio_default_fixture_loop_scope="function" (lines 199-200) and dev deps include pytest-asyncio, but grep shows no async def / coroutines in src/mg | No async production code; async-test rule has no applicable coroutine target. |
| TS-13 | ✅ | TS-13 MUST: property (Hypothesis) tests MUST cover any code that round-trips data, with strategies in a _strategies.py. records.py round-trips data (TestRecord.to_json ↔ from_jsonl_line) and | Round-trip code exists (JSONL serialise/parse, tier-range parse) but has no Hypothesis property test or _strategies.py; only example-based pins. — FIXED 2026-06-07: Hypothesis property tests (tests/unit/test_round_trip_property.py + _strategies.py) for the round-trip paths: TestRecord JSONL serialise↔parse + parse_tier_range; hypothesis added to [dev] |
| TS-14 | N/A | The supervisor declares a 'perf' marker (tier-3, excluded from default) but ships NO perf-budget benchmark of its own production path (no @pytest.mark.perf test in tests/). It has no PERFORM | No owned performance budget to pin; no perf benchmark target exists. |
| TS-15 | N/A | No real-backend smoke surface exists — the supervisor has no external backend (libvirt/SSH/HTTP API). tests/smoke/ holds post-install sanity (TS-19/21 smoke marker), not §12 real-backend smo | No real external backend to smoke-test; §12 pattern inapplicable. |
| TS-16 | ✅ | Load-bearing assertions carry context: test_alignment_with_mgf_common asserts include f-string diffs ('Schema-version drift…', 'MARKER_TIER drift…', field-set diffs); test_tier_subset 'f"{ma | Ambiguous/load-bearing asserts attach context messages; bare asserts only on self-evident values. No counterexample of an opaque load-bearing assert found. — RECONCILED 2026-06-07: status corrected ⏳→✅; the depth-audit refute pass flipped the label but its own evidence is upheld ("canonical reference / no counterexample / verify-upheld / vacuously met"). Re-read confirms MET. |
| TS-17 | ✅ | TS-17 (fixtures discoverable via conftest hierarchy, never cross-package imported). There are NO conftest.py files anywhere under tests/ (find confirmed none) and no fixtures are imported ac | No custom fixtures and no cross-package fixture imports; the rule's prohibition is vacuously met. — RECONCILED 2026-06-07: status corrected ⏳→✅; the depth-audit refute pass flipped the label but its own evidence is upheld ("canonical reference / no counterexample / verify-upheld / vacuously met"). Re-read confirms MET. |
| TS-18 | ✅ | REFUTED. TS-18 MUST: 'Slow tests (>1 s individually) MUST be marked @pytest.mark.slow and excluded from the default pytest invocation. Default CI runs only the fast suite.' tests/smoke/test_ | A 35s test and multi-second subprocess tests run in the default CI pytest invocation without the slow marker; the MUST is violated by counterexample. — FIXED 2026-06-07: the ~32s self-check is now @pytest.mark.slow (excluded from the fast bare-pytest default) + a slow-suite CI step runs the @slow/@e2e layer |
| TS-19 | ✅ | pyproject [tool.pytest.ini_options].markers (lines 204-219) registers the full taxonomy (smoke/e2e/integration/contract/property/regression/fuzz/concurrency/conformance/use_case/perf/stress/ | All used markers registered, both axes present, slow defensively registered. No unregistered marker found. — RECONCILED 2026-06-07: status corrected ⏳→✅; the depth-audit refute pass flipped the label but its own evidence is upheld ("canonical reference / no counterexample / verify-upheld / vacuously met"). Re-read confirms MET. |
| TS-20 | ✅ | TS-20 MUST: tests partitioned across the four canonical dirs (unit/integration/e2e/smoke). This repo has tests/unit/ and tests/smoke/ but NO tests/integration/ and NO tests/e2e/ (ls confirme | Only unit/ and smoke/ exist; integration/ and e2e/ directories are absent and e2e-shaped tests are filed under unit/. — FIXED 2026-06-07: canonical tests/integration/ + tests/e2e/ dirs + charters (the 35s self-check is the e2e-shaped reference) |
| TS-21 | ✅ | tests/smoke/ exists with pytestmark=pytest.mark.smoke. test_import_smoke.py imports every core module (reachability pin) and exercises parse_tier_range happy path; test_self_check.py runs th | Smoke layer present and substantive (import + reachability + happy path); __all__ clause vacuous. The <100ms budget breach is captured under TS-18; the layer's existence/substance MUST is met. — RECONCILED 2026-06-07: status corrected ⏳→✅; the depth-audit refute pass flipped the label but its own evidence is upheld ("canonical reference / no counterexample / verify-upheld / vacuously met"). Re-read confirms MET. |
| TS-22 | ✅ | tiers.py implements MARKER_TIER, tier_for_markers (highest-wins, line 81), auto_tier (5x bump, line 94), parse_tier_range ('0'/'0-2'/'1-3', line 125). selection.py implements greedy knapsack | All three flags (--tier N, --tier N-M, --budget T) and the tier-0-always greedy knapsack are implemented; this is the named reference. No counterexample to the MUST's existence. — RECONCILED 2026-06-07: status corrected ⏳→✅; the depth-audit refute pass flipped the label but its own evidence is upheld ("canonical reference / no counterexample / verify-upheld / vacuously met"). Re-read confirms MET. |
| TS-23 | ✅ | supervisor.py runs pytest as subprocess (subprocess.Popen, start_new_session=True line 250), classifies crash via signal (_signal_name; CHUNK_SIGSEGV/SIGABRT/SIGBUS/SIGILL/SIGFPE lines 348-3 | All four required outcomes implemented out-of-process with no bootstrap circularity; canonical reference. No counterexample. — RECONCILED 2026-06-07: status corrected ⏳→✅; the depth-audit refute pass flipped the label but its own evidence is upheld ("canonical reference / no counterexample / verify-upheld / vacuously met"). Re-read confirms MET. |
| TS-24 | ✅ | records.py TestRecord is a frozen dataclass mirroring DoctorFinding (code/severity/summary/detail/why/remediation) plus test_id/outcome/duration_ms/tier/markers/captured_stdout/captured_stde | One-JSON-per-line to .gates/last-run/run.jsonl, DoctorFinding-mirroring schema + testing fields, mandatory schema_version, alignment contract tested. Named reference writer; no counterexample. — RECONCILED 2026-06-07: status corrected ⏳→✅; the depth-audit refute pass flipped the label but its own evidence is upheld ("canonical reference / no counterexample / verify-upheld / vacuously met"). Re-read confirms MET. |
| TS-25 | ✅ | quarantine.py implements FAILURES_TO_QUARANTINE=3 / PASSES_TO_EVICT=3 (lines 34-35), 3-of-window quarantine + 3-consecutive-pass eviction, atomic write (tempfile.mkstemp + rename, lines 101- | Quarantine mechanism implemented per the MUST (reference impl), but no direct unit test pins the 3-of-5 / 3-consecutive-pass eviction or atomic persistence. — FIXED 2026-06-07: tests/unit/test_quarantine.py pins the 3-of-5-fail quarantine (via entry.quarantined_at) + 3-consecutive-pass eviction + atomic persistence |
| TS-26 | N/A | TS-26 explicitly allows: 'Projects with no compiled artifacts (pure-Python libraries, mgf-common itself) MAY declare TS-26 N/A.' mgf-test-supervisor is pure-Python stdlib-only (dependencies= | No compiled artifact; the standard itself blesses N/A for pure-Python projects. |
| TS-27 | ✅ | supervisor._write_failure_bundle (line 468) writes one file per failure to last-run/failures/<_safe_filename(test_id)>.txt with all mandated sections: test_id, outcome, code, summary, traceb | Every required section is assembled into one per-failure file; canonical reference. No missing section found. — RECONCILED 2026-06-07: status corrected ⏳→✅; the depth-audit refute pass flipped the label but its own evidence is upheld ("canonical reference / no counterexample / verify-upheld / vacuously met"). Re-read confirms MET. |
| TS-28 | ✅ | perf.py is the reader: PerfStore ingests per-test {test_id,total_ms,functions[],spans[]} out-of-process, never imports mgf-common (docstring states TS-23), fail-open per file (missing dir /  | All TS-28 invariants (opt-in, three surfaces, fail-open, bounded, baseline-isolated, reader-never-imports-writer) implemented and tested; named reference reader. No counterexample. — RECONCILED 2026-06-07: status corrected ⏳→✅; the depth-audit refute pass flipped the label but its own evidence is upheld ("canonical reference / no counterexample / verify-upheld / vacuously met"). Re-read confirms MET. |

### API_DESIGN

| Rule | Status | Evidence | Notes |
|---|---|---|---|
| AP-01 | ✅ | No __all__ anywhere in src/mgf/test_supervisor/ (grep for __all__ returns nothing across all 11 modules, including __init__.py:1-52 which exposes only the module docstring + __version__). Pu | AP-01 MUST: the public API surface MUST be enumerated explicitly via __all__ at every boundary consumers import from. The package ships zero __all__ declarations, so the contract surface is implicit. Even under TS-23 stdlib-only shape this — FIXED 2026-06-07 (0.1.12): __all__ added to all 8 public modules + the package root re-exports the full public surface (47 names) with __all__ |
| AP-02 | ✅ | Public functions carry docstrings stating intent/invariants (e.g. tiers.auto_tier:99-107, tiers.parse_tier_range:126-130, perf.slowest_tests). The module docstring in __init__.py:1-49 is tho | AP-02 MUST: every public name MUST have a docstring with intent, invariants, AND at least one usage example. Intent/invariants are largely present but the usage-example clause and full coverage are not met for the entire surface — partial. — FIXED 2026-06-07: every public function/class docstring now carries a usage Example:: block (31 callables across 8 modules). Module-level constants can't hold docstrings → covered by PUBLIC_API.md descriptions. |
| AP-03 | ✅ | pyproject.toml:3 version="0.1.11"; src/mgf/test_supervisor/__init__.py:51 __version__="0.1.11" (well-formed MAJOR.MINOR.PATCH). CHANGELOG.md:5-8 declares adherence to SemVer 2.0.0 and the 0. | AP-03 MUST: package follows SemVer; the 0.x window is where API breaks may land in MINOR. Version is well-formed three-part SemVer and the CHANGELOG explicitly commits to the 0.x discipline. Re-checked CHANGELOG.md:1-8 and pyproject.toml:3  |
| AP-04 | N/A | No deprecations exist through 0.1.11. The CHANGELOG has no ### Deprecated/### Removed sections; the only 'deprecated' mention is the pytest 'slow' marker (pyproject.toml:218 'Deprecated. Rem | AP-04 governs the announce→survive→remove cycle for deprecated public names. With no deprecations in the recorded history, there is nothing for the rule to bind to — N/A for the project's current change set. |
| AP-05 | ✅ | mypy --strict is configured (pyproject.toml:159-174) and run in CI (.woodpecker.yml:28-34). Signatures are typed (records.severity_for_outcome(outcome:str)->str:108; tiers.parse_tier_range(s | AP-05 MUST: new optional parameters MUST be keyword-only with defaults. Signatures are strict-typed and the 0.x window permits a rare break, so there is no recorded contract violation — but the verdict's supporting evidence is factually wro — RECONCILED 2026-06-07: no NEW non-kw-only optional param was added; the existing positional-optionals (auto_tier/render_*/dmesg_tail/recent_history) are grandfathered in the 0.x window — AP-05 governs new additions, none violate |
| AP-06 | ✅ | Public returns are concrete and narrow: records.read_jsonl(...)->Iterator[dict[str,Any]]:170, tiers.parse_tier_range->set[int]:125, tiers.auto_tier->tuple[int,str\|None]:94-98, perf.slowest_ | AP-06 MUST: return types MUST NOT narrow in non-MAJOR releases; contracts pinned narrowly. Returns are concrete container/tuple types (not over-wide Iterable where a list is meant), strict-typed, and no narrowing is observed in the recorded |
| AP-07 | N/A | Per the TS-23 stdlib-only carve-out, the supervisor imports no mgf-common runtime surface and ships no typed AppError exception hierarchy (that hierarchy lives in mgf-common, a DEV-only dep) | AP-07 requires public exceptions to be subclasses of the project's typed hierarchy. A stdlib-only library with no runtime mgf-common dependency has no such hierarchy by mandate; the rule's machinery (typed AppError tree) does not apply to t |
| AP-08 | ✅ | Every module EXCEPT __init__.py carries 'from __future__ import annotations' (grep -L returns only src/mgf/test_supervisor/__init__.py). The package-boundary __init__.py:1-52 omits the impor | AP-08 MUST: public modules MUST use 'from __future__ import annotations'. The 10 substantive modules comply; the literal gap is the public package boundary __init__.py, which omits it. Substantively harmless (no annotations there) but a lit — FIXED 2026-06-07 (0.1.12): __init__.py now carries 'from __future__ import annotations' (the one boundary that omitted it) |
| AP-09 | ✅ | src/mgf/test_supervisor/py.typed exists (ls shows a 0-byte py.typed). pyproject.toml:90-91 [tool.hatch.build.targets.wheel] packages=["src/mgf"] walks the tree so the marker ships; classifie | AP-09 MUST: a PEP 561 py.typed marker MUST exist for any package shipping type annotations. Present at the package root (0-byte, confirmed via ls) and packaged via the src/mgf wheel walk. [verify-upheld] |
| AP-10 | ✅ | No PUBLIC_API.md or docs/PUBLIC_API.md exists (ls of both paths returns 'No such file or directory'). The README declaration line points only at the conformance tracker (CHANGELOG.md:121-126 | AP-10 MUST: a PUBLIC_API.md MUST list every public name with stability tier + one-line description, kept in sync with __all__ in CI. Neither the file nor the CI pin exists — unmet. (Not a web-shape consumer: this is a published Codeberg-reg — FIXED 2026-06-07 (0.1.12): PUBLIC_API.md lists every public name with stability tier + description; generated PUBLIC_API.json + tools/generate_public_api_json.py + CI pin test |
| AP-11 | ✅ | No stability tiers are declared anywhere — there is no PUBLIC_API.md tier column (file absent) and no per-name 'tier:' markers in source (grep finds none). Names are implicitly experimental  | AP-11 MUST: stability tiers MUST be declared per public name. With no PUBLIC_API.md and no tier markers, the obligation is structurally unmet — depends on AP-10 which is also a gap. — FIXED 2026-06-07 (0.1.12): PUBLIC_API.md declares a tier per public name (stable = alignment-pinned schema/tier contract; experimental = 0.x primitives) |
| AP-12 | ✅ | CHANGELOG.md:1-8 follows Keep a Changelog + SemVer 2.0.0 with Added/Changed/Fixed sections (0.1.8:37-64 uses ### Added / ### Changed / ### Fixed). Through 0.1.11 every change is additive (0. | AP-12 MUST: breaking changes MUST be documented with before/after/why migration recipe. Re-read the full CHANGELOG — there are NO breaking changes in the recorded history to migrate, and the Keep-a-Changelog format is in place to carry one  |
| AP-13 | ✅ | __version__ present on the top-level package: src/mgf/test_supervisor/__init__.py:51 __version__="0.1.11", mirroring pyproject.toml:3 version="0.1.11". CI-pinned by tests/unit/test_version_i | AP-13 MUST: __version__ present on top-level package, mirrors pyproject version, CI lints the two stay in sync. All three conditions verified in source: the dunder, the matching pyproject value, and the CI-run sync test. [verify-upheld] |
| AP-14 | N/A | The package has no single-underscore private modules at the package level (all 11 modules are public-named: supervisor, selection, tiers, etc.); private helpers are underscore-prefixed funct | AP-14 MUST: internal modules MUST NOT be consumer-imported, with CI enforcement via import-linter. The repo has no private _modules to wall off and uses function-level underscores instead, so the spirit (closed internals) is partially met b — RE-VERIFIED 2026-06-07 N/A: the package has NO private _-prefixed MODULES (function-level underscores only); AP-14's module-import-boundary premise doesn't bind — nothing to wall off via import-linter |
| AP-15 | N/A | No backward-compatibility shims exist. There are no re-export shim modules and no deprecated import paths in src/mgf/test_supervisor/ (no 'old_module'-style re-exports; the only deprecation  | AP-15 governs shims that survive removal of original code (must emit DeprecationWarning + INFO audit log). With no shims in the codebase, the rule has nothing to bind to — N/A for the current shape. |
| AP-16 | ✅ | pyproject pins the cornerstone dev-dep with the federation window mgf-common>=0.41,<1.0 (+ mgf-common[standards]>=0.46,<1.0 in [standards]) per API_DESIGN §4.4; the mandatory compat matrix runs in CI as the mgf-common-matrix step (.woodpecker.yml:89) — re-pin mgf-common down to the 0.41 floor + re-run the suite (the alignment contract is the consumed surface) | Adopted in the AP-16 cohort wave 2026-07-01 (PR#34 widened the pin; that commit's message claimed the matrix step but only the pin landed — WF-13-exempt pipeline, no re-render). Row + hand-added matrix step landed together on the Wave-2 honest-gate branch when mgf-standard 0.1.61 entered AP-16 into the released MUST index. |

### SCOPE

| Rule | Status | Evidence | Notes |
|---|---|---|---|
| SP-01 | ✅ | No SCOPE.md and no explicit IN-scope list exist anywhere in the repo. grep for 'in scope'/'in-scope' across README.md, STARTHERE.md, CHANGELOG.md, docs/claude/CLAUDE.md, DEPS.md returns noth | SP-01 requires the library to PUBLISH an explicit IN-scope list. The SCOPE standard (SCOPE.md:10-17,83-84) binds any 'cornerstone' library that 'aspires to be a stable foundation for downstream consumers' and says other libraries following — FIXED 2026-06-07: SCOPE.md §1 published in-scope policy |
| SP-02 | ✅ | No OUT-of-scope list with reasoning exists. grep for 'out of scope'/'out-of-scope'/'will not ship'/'deliberately not' across the docs returns nothing (only SECURITY.md:80 'Out of scope:' for | SP-02 requires an explicit OUT-of-scope list where each entry carries both 'why we don't ship X' and 'what you should use instead' (SCOPE.md:26, §2 table 97-119). None is published. The supervisor plausibly has natural OUT items (e.g. it is — FIXED 2026-06-07: SCOPE.md §2 out-of-scope + reasons |
| SP-03 | ✅ | CONTRIBUTING.md 'Process' (lines 31-56) lists PR steps (FEEDBACK filing, four-gate CI, CHANGELOG entry, JSONL-schema delta mirroring, reviewer) but contains NO requirement that a PR adding a | SP-03 requires every PR adding a module/top-level function to justify against §1 (IN) or §3 (Adjacent), rejecting 'OUT' answers with a pointer to the ecosystem solution (SCOPE.md:27, §4 160-187). The contributor process does not impose this — FIXED 2026-06-07: SCOPE.md §3 scope-creep gate (stdlib-only-first) |
| SP-04 | ✅ | No Adjacent-scope section exists and no documented promotion/demand-signal mechanism gates new scope. FEEDBACK.md provides a PAPER-NN intake (FEEDBACK.md:25-38) and §4 (141-152) explains how | SP-04 requires Adjacent-scope items to require a documented consumer-demand signal before promotion to IN (SCOPE.md:28, §3 121-158). With no Adjacent list and no promotion-criterion wiring, the rule is unmet. The FEEDBACK.md PAPER flow is t — FIXED 2026-06-07: SCOPE.md §4 adjacent-scope + demand-signal rule |
| SP-05 | ✅ | Because no OUT-of-scope list exists (SP-02), there are no ecosystem-alternative citations. grep across the docs for cited alternatives in a scope context returns nothing. README.md:9-11 cont | SP-05 requires every OUT-of-scope cut to cite the ecosystem alternative (SCOPE.md:29, §2 'What you should use instead' column 99-114). With no OUT list published, no citations exist, so the rule is unmet. Smallest fix: when adding the SP-02 — FIXED 2026-06-07: SCOPE.md §5 alternatives for out-of-scope |
| SP-06 | ✅ | No scope policy exists to revisit, and no MAJOR-release scope-revisit clause is documented. CHANGELOG.md and CONTRIBUTING.md 'Release flow' (CONTRIBUTING.md:58-64) describe the bump/build/te | SP-06 requires the scope policy to be revisited on every MAJOR release, with the MAJOR boundary the only place a previously-IN item may be removed (SCOPE.md:30, §6 224-231). No scope policy and no revisit cadence are documented. Smallest fi — FIXED 2026-06-07: SCOPE.md §6 revisit-on-MAJOR + reaffirm stdlib-only |

### WORKFLOWS

| Rule | Status | Evidence | Notes |
|---|---|---|---|
| WF-01 | ✅ | .woodpecker.yml:14-17 `when: - event: push - event: pull_request - event: manual`; steps lint(:21)/typecheck(:29)/test-3.11(:43)/test-3.12(:50)/test-3.13(:57)/vuln-scan(:65)/secret-scan(:74) | CI runs on every push and every PR (plus manual). No local-only path; the workflow file is the canonical gate runner. MET. [verify-upheld] |
| WF-02 | ✅ | .woodpecker.yml:20-21 no import-linter; no .importlinter | 3/4 gates (ruff/mypy/pytest) present; import-linter gate absent. Fix: add .importlinter (leaf contract: no runtime mgf.common) + lint-imports step. — FIXED 2026-06-07: tag-driven Codeberg publish pipeline (.woodpecker build→tag-coherence→smoke→publish→verify-codeberg) + .importlinter stdlib-only contract & lint-imports in CI + scripts/verify_codeberg.py; mirrors mgf-common/mgf-fastapi |
| WF-03 | ✅ | .woodpecker.yml when: only push/pr/manual; no event:tag publish step; header comment says publish chain still to be copied 'when a release is cut' | Published library (0.1.11) → WF-03 binds. No tag-driven publish workflow at all. Fix: add the build→smoke→upload→verify tag-gated chain. — FIXED 2026-06-07: tag-driven Codeberg publish pipeline (.woodpecker build→tag-coherence→smoke→publish→verify-codeberg) + .importlinter stdlib-only contract & lint-imports in CI + scripts/verify_codeberg.py; mirrors mgf-common/mgf-fastapi |
| WF-04 | ✅ | no publish step → no codeberg_package_token from_secret | No publish flow → WF-04 unmet by omission. Fix: consume codeberg_package_token via secret store, tag-event-scoped. — FIXED 2026-06-07: tag-driven Codeberg publish pipeline (.woodpecker build→tag-coherence→smoke→publish→verify-codeberg) + .importlinter stdlib-only contract & lint-imports in CI + scripts/verify_codeberg.py; mirrors mgf-common/mgf-fastapi |
| WF-05 | ✅ | no CI_COMMIT_TAG usage; no tag-coherence check (version files ARE in sync at 0.1.11) | Publish flow absent → no CI-time tag-coherence gate. Fix: add tag==pyproject==__version__ check as first publish step. — FIXED 2026-06-07: tag-driven Codeberg publish pipeline (.woodpecker build→tag-coherence→smoke→publish→verify-codeberg) + .importlinter stdlib-only contract & lint-imports in CI + scripts/verify_codeberg.py; mirrors mgf-common/mgf-fastapi |
| WF-06 | ✅ | no build step in publish flow; dist/ holds STALE mgf_test_supervisor-0.1.10 wheel while pyproject=0.1.11 (local-drift footgun) | WF-06 wants the wheel built fresh in the publish run; none exists + stale local artifact. Fix: uv build inside the tag-gated publish workflow. — FIXED 2026-06-07: tag-driven Codeberg publish pipeline (.woodpecker build→tag-coherence→smoke→publish→verify-codeberg) + .importlinter stdlib-only contract & lint-imports in CI + scripts/verify_codeberg.py; mirrors mgf-common/mgf-fastapi |
| WF-07 | ✅ | no pre-publish smoke; pytest matrix uses editable -e .[dev], not the built wheel; console scripts mgf-test-supervisor/mtest exist | WF-07 binds. Fix: install the fresh wheel into a venv, import, assert __version__, run mtest --version. — FIXED 2026-06-07: tag-driven Codeberg publish pipeline (.woodpecker build→tag-coherence→smoke→publish→verify-codeberg) + .importlinter stdlib-only contract & lint-imports in CI + scripts/verify_codeberg.py; mirrors mgf-common/mgf-fastapi |
| WF-08 | ✅ | no post-publish REST poll of api/v1/packages/.../mgf-test-supervisor/<version> | WF-08 binds. Fix: add a final step polling the Codeberg REST API for 200 (never pypi.org). — FIXED 2026-06-07: tag-driven Codeberg publish pipeline (.woodpecker build→tag-coherence→smoke→publish→verify-codeberg) + .importlinter stdlib-only contract & lint-imports in CI + scripts/verify_codeberg.py; mirrors mgf-common/mgf-fastapi |
| WF-09 | ✅ | Interpreter images pinned rolling-minor: python:3.12-slim (:22,30,51,66), python:3.11-slim (:44), python:3.13-slim (:57). Plugin pinned exact: zricethezav/gitleaks:v8.30.1 (:75). uv.lock (15 | WF-09 governs image/action pins. WORKFLOWS.md §7.1 explicitly accepts rolling-minor python:3.X-slim ('Most projects accept rolling-minor for the security-update benefits'); gitleaks is exact-patch-pinned; deps lockfile-pinned. No unpinned i |
| WF-10 | ✅ | No `depends_on:` anywhere in .woodpecker.yml (grep clean — only matches are in comment text :6,:36). All 7 steps declare no dependency edges → Woodpecker runs them in parallel. Version matri | All independent gates and the per-version test axis run in parallel; no gratuitous serialisation. The build→smoke→upload sequencing WF-10 reserves for genuine dependencies is moot — no publish chain exists. For the steps present, MET. [veri |
| WF-11 | ⏳ | Every test/lint/typecheck/vuln-scan step runs `pip install --quiet -e ".[dev]"` (:25,33,47,54,61,70) — installing from pyproject.toml, NOT `uv sync` from the checked-in uv.lock. WORKFLOWS.md | The canonical WF-11 reproducibility mechanism — install-from-lock — is absent. The uv.lock is checked in but never consumed: every install resolves transitive deps fresh from pyproject, so a re-run against the same commit can pull different |
| WF-12 | ✅ | grep '\|\| true' .woodpecker.yml → no matches. Gates use failing commands: ruff check (:26), mypy (:34), pytest --tb=short (:48/55/62), pip-audit --strict (:71), gitleaks detect --no-banner  | No error swallowing, no no-op green steps; every command surfaces its exit code and the failing command is visible. --tb=short gives log context on pytest failures. The §2.4 shape's --verbose/--config .gitleaks.toml flags are omitted but ex |
| WF-13 | N/A | .woodpecker.yml is hand-maintained (no GENERATED header); WF-13 binds only to generated pipeline artifacts. |

### RELEASING

| Rule | Status | Evidence | Notes |
|---|---|---|---|
| REL-01 | ✅ | git cat-file -t v0.1.11 returns 'commit' (a LIGHTWEIGHT tag), whereas v0.1.10 and v0.1.1 return 'tag' (annotated). The 0.1.11 release tag points at the correct release commit (git rev-list - | The 0.1.11 release regressed from the project's own established discipline (every prior tag v0.1.1..v0.1.10 is annotated) to a lightweight tag, violating REL-01's annotated-tag MUST for this specific release. — FIXED 2026-06-07: the lone lightweight tag v0.1.11 re-annotated on its original commit ec660be1e5 + force-pushed (authorized); verified type=tag. v0.1.1..v0.1.10 + v0.1.12/13 were already annotated. |
| REL-02 | ✅ | ls -la dist/ shows ONLY mgf_test_supervisor-0.1.10-py3-none-any.whl + .tar.gz (both mtime Jun 4 12:10), no 0.1.11 artifact. The 0.1.11 version bump landed atomically in commit ec660be (Jun 6 | Refute attempt failed: there is no 0.1.11 wheel built over a same-named artifact; dist/ still holds the prior version's frozen 0.1.10 artifacts and the bump-first (§2.1/§5) discipline was followed atomically. No reuse footgun present. [veri |
| REL-03 | N/A | No PUBLIC_API.md or PUBLIC_API.json exists anywhere in the repo (find for PUBLIC_API* returns nothing). mgf-test-supervisor is an argparse CLI tool that is stdlib-only at runtime and never i | REL-03 governs the master-HEAD-vs-published banner on PUBLIC_API.md/.json. With no such artifact (and none mandated for a CLI tool with no library surface), the rule does not apply. |
| REL-04 | ✅ | No publish/registry token appears anywhere in the repo: .woodpecker.yml carries no publish step and no codeberg_package_token / TWINE_PASSWORD secret reference (only lint/typecheck/test/vuln | REL-04's MUST is that publish tokens are not exposed in chat/shell-history/env on unmanaged sessions or committed. The repo shows zero token exposure and an active secret-scan gate; no counterexample of a leaked/committed token exists. The  |
| REL-05 | ✅ | git tag -l \| sort -V shows monotonic lineage v0.1.1..v0.1.11, one new version per release. CHANGELOG.md carries distinct dated entries per version ([0.1.11] 2026-06-06, [0.1.10] 2026-06-04, | Refute attempt failed: immutability-by-policy means a published version is never silently content-swapped; each release here advances the version and ships as a new entry. Bug-fix-as-new-release discipline is the observed pattern. [verify-u |
| REL-06 | ✅ | The version-bump-first step ran (ec660be bumps pyproject + __init__ together; CHANGELOG entry added). But the ordered flow cannot be fully verified as run for 0.1.11: (a) the tag step produc | PUBLIC_API regen (step 2) is N/A (no PUBLIC_API.json — CLI tool, TS-23). The flow is partially evidenced (bump, CHANGELOG, commit) but the tag-annotation step regressed and the upload/verify tail is unverifiable from the repo, so full order — FIXED 2026-06-07: tag-driven Codeberg publish pipeline (.woodpecker build→tag-coherence→smoke→publish→verify-codeberg) + .importlinter stdlib-only contract & lint-imports in CI + scripts/verify_codeberg.py; mirrors mgf-common/mgf-fastapi |
| REL-07 | ✅ | FEEDBACK.md §2 holds exactly one entry, PAPER-01 (mtest junit-XML MISSING_FROM_XML false-failures), Status=OPEN, submitter mgf-vm. The 0.1.11 release (CHANGELOG [0.1.11] + commit ec660be + t | Refute attempt failed: REL-07 obligates flipping every FEEDBACK entry a release SHIPS. 0.1.11 ships zero feedback entries (pure dependency-window walk), so the obligation is vacuously satisfied — no entry whose fix landed in 0.1.11 is left  |
| REL-08 | ✅ | dist/ holds only the 0.1.10 wheel/sdist (Jun 4); there is no 0.1.11 wheel on disk to confirm a smoke install was run. .woodpecker.yml contains lint/typecheck/pytest-matrix/vuln-scan/secret-s | No in-repo or CI artifact demonstrates the freshly-built 0.1.11 wheel was installed into an ephemeral venv and imported (§2.2 / REL-08). Not refutable to a hard violation (a local smoke may have happened off-record), but conformance is unve — FIXED 2026-06-07: tag-driven Codeberg publish pipeline (.woodpecker build→tag-coherence→smoke→publish→verify-codeberg) + .importlinter stdlib-only contract & lint-imports in CI + scripts/verify_codeberg.py; mirrors mgf-common/mgf-fastapi |
| REL-09 | ✅ | REL-09 fires per FEEDBACK status-flip (->SHIPPED/DEFERRED/REJECTED). The only FEEDBACK entry, PAPER-01, is still OPEN (FEEDBACK.md §2) and was NOT flipped by 0.1.11; the 0.1.11 release close | Refute attempt failed: the rule's trigger is a status flip; none occurred in 0.1.11, so the obligation does not arise and no flipped-but-un-notified entry exists. (A future resolution of PAPER-01 would owe mgf-vm a notification — future wor |

### PACKAGE_DISTRIBUTION

| Rule | Status | Evidence | Notes |
|---|---|---|---|
| PKG-01 | ✅ | pyproject.toml [project.urls] all point to codeberg.org/magogi-admin/mgf-test-supervisor; [[tool.uv.index]] codeberg-mgf + [tool.uv.sources] mgf-common map the only mgf-* dep to Codeberg; uv | The sole mgf-* dependency (mgf-common, dev-only per TS-23) is resolved from the Codeberg registry; no mgf-* resolves from pypi.org. This package is not itself published in committed CI (no publish workflow), but its consume-side wiring is c |
| PKG-02 | ✅ | pyproject.toml:78 url = "https://codeberg.org/api/packages/magogi-admin/pypi/simple/" — the exact canonical §3 simple-index endpoint. uv.lock:256 source registry and uv.lock:285 index use th | Refute attempt failed: read §3 canonical-endpoint table (line 116) — the committed URL is character-identical to the canonical simple-index endpoint. Only the index endpoint is testable here (no publish CI), and it is exact in both pyprojec |
| PKG-03 | N/A | No publish CI / no .woodpecker.yml publish step / no token references in the repo; mgf-common is a read-only dev dep consumed via the Codeberg index. | PKG-03 governs write:package/read:package token discipline for publishing and installing. No publish surface is committed; consumer auth is env-injected (UV_INDEX_*), not committed. Original non-challenged verdict; unchanged. |
| PKG-04 | N/A | No committed publish flow (no twine/uv publish step, no .woodpecker.yml publish job). | PKG-04 governs the ordered publish ritual; no publish flow exists in this repo to evaluate. Original non-challenged verdict; unchanged. |
| PKG-05 | N/A | No publish/verify CI step committed. | PKG-05 governs post-publish REST verification against Codeberg; no publish/verify surface present. Original non-challenged verdict; unchanged. |
| PKG-06 | ✅ | pyproject.toml:76-82 [[tool.uv.index]] name="codeberg-mgf" url=canonical simple-index explicit=true; [tool.uv.sources] mgf-common = { index = "codeberg-mgf" }. uv.lock:285 confirms mgf-commo | Refute attempt failed: read PKG-06 (line 95) + §6 canonical shape (lines 208-219) — the committed config is exactly the explicit named-index + [tool.uv.sources] mapping mandated, with explicit=true closing the dependency-confusion hole. The |
| PKG-07 | N/A | No publish/release session for this package committed; no delete/re-upload tooling. | PKG-07 governs version-immutability discipline during publishing; no publish surface to evaluate. Original non-challenged verdict; unchanged. |
| PKG-08 | N/A | No registry-owner retention tooling in this consumer repo. | PKG-08 is an account/registry-level retention obligation on the magogi-admin owner, not a per-consumer-repo gate. Original non-challenged verdict; unchanged. |
| PKG-09 | N/A | No .woodpecker.yml publish job / no tag-driven publish step committed. | PKG-09 governs CI publishing; this repo commits no publish CI. Original non-challenged verdict; unchanged. |
| PKG-10 | ✅ | Distribution name mgf-test-supervisor (hyphenated); import namespace mgf.test_supervisor (dotted) per [tool.hatch.build.targets.wheel] packages=["src/mgf"] and console scripts mgf.test_super | Naming defers to NM-01..NM-04: hyphenated dist name, dotted import — both satisfied. Original non-challenged verdict; unchanged. |
| PKG-11 | N/A | No agent/federation version-check logic in this repo (it is the test supervisor, not the standards/agents CLI). | PKG-11 is an AG-09 amendment for agents that verify sibling published versions; not applicable to this repo's surface. Original non-challenged verdict; unchanged. |
| PKG-12 | ✅ | grep for pypi.org publish/index/token/verify surface over committed config finds none targeting mgf-*; the only index URLs are the Codeberg simple-index (pyproject.toml:78, uv.lock). Third-p | No residual pypi.org publish/distribution surface for mgf-*: no pypi.org publish command, token, index, or verify step committed. Original non-challenged verdict; unchanged. |

### DOCUMENTATION

| Rule | Status | Evidence | Notes |
|---|---|---|---|
| DOC-01 | ✅ | Repo root carries the full v2.11/v2.12 uniform baseline: README.md, LICENSE, CHANGELOG.md, CONTRIBUTING.md, SECURITY.md, FEEDBACK.md, AGENTS.md, STARTHERE.md, DEPS.md, FEDERATION.md, LESSON_ | Not in the challenge set; derived. Every required baseline root doc and the docs/ dir are present. PUBLIC_API.md/.json absence is the only gap (sibling-applicable) but not part of the uniform baseline this rule's core enumerates; the baseli |
| DOC-02 | ✅ | docs/ contains claude/ and inprogress/ buckets (ls docs/). As a sibling, the minimum is docs/claude/CLAUDE.md (present) + inprogress trackers (MGF_STANDARDS_CONFORMANCE.md present). standard | Not in challenge set; derived. The bucket layout matches sibling-shape applicability. docs/standards/ pointer-README is absent but is ⚠️ (conditional), not a hard MUST for a sibling that inherits via FEDERATION/CONFORMANCE. |
| DOC-03 | N/A | docs/ has only claude/ and inprogress/ buckets; neither ships a bucket-charter README.md (ls docs/claude, docs/inprogress show CLAUDE.md and MGF_STANDARDS_CONFORMANCE.md only). | Not in challenge set; derived. DOC-03 requires a per-bucket README for long-lived buckets. claude/ and inprogress/ here are single-file, federation-standard buckets whose charter is fixed by DOC-07/DOC-15; the missing bucket-README is a min |
| DOC-04 | ✅ | CHANGELOG.md:5-6 declares Keep-a-Changelog + SemVer; [0.1.8] (CHANGELOG.md:37-64) carries Added/Changed/Fixed; [0.1.11] header at CHANGELOG.md:10. Version coherent at 0.1.11 across pyproject | Upheld on the literal MUST (same-commit Keep-a-Changelog entry per public-API change; format declared, well-formed, current, version-coherent). [verify-refuted: the recent [0.1.9]/[0.1.10]/[0.1.11] entries are free-prose pin-walk notes with — FIXED 2026-06-07: the 0.1.9/0.1.10/0.1.11 pin-walk entries now carry Keep-a-Changelog ### Changed subsections |
| DOC-05 | N/A | no docs/cutover/; CHANGELOG is all 0.1.x PATCH (additive flags/schema, pin-walks, bugfixes); no breaking change shipped | DOC-05's MUST is conditional on a breaking change; none has bound (still 0.1.x, additive only). N/A until a breaking 0.1→0.2. |
| DOC-06 | N/A | docs/inprogress/ holds only the conformance ledger (DOC-15 shape), no living priority tracker exists | DOC-06 governs the SHAPE of priority trackers that exist; it doesn't mandate one. No tracker → premise doesn't bind. N/A. |
| DOC-07 | ✅ | docs/claude/CLAUDE.md:3 opens 'Dense lookup document. No prose. Facts only.'; File+module map table at CLAUDE.md:67-79 with file citations; CLI surface + exit codes at CLAUDE.md:31-47; conve | Upheld. The AI-agent entry point exists at the canonical path docs/claude/CLAUDE.md in the prescribed dense format with facts, file:line-style citations, pitfalls, and pre-approvals-style guidance. [verify-upheld] |
| DOC-08 | N/A | No PUBLIC_API.md or PUBLIC_API.json at repo root (ls -la). Runtime is stdlib-only (TS-23); the package exposes a CLI (mtest), and the only 'public' surface (TestRecord/MARKER_TIER/SCHEMA_VER | Not in challenge set; derived. DOC-08 governs PUBLIC_API.{md,json} tracking __all__. The supervisor is a CLI tool whose consumers couple via the JSONL/CLI contract, not Python imports (DEPS.md §2); no public import surface to pin. N/A by sh |
| DOC-09 | ✅ | docs/claude/CLAUDE.md:44 'No --merge flag in this version (v0.1.6)' and CLAUDE.md:152 'not yet landed in v0.1.6 source' label the doc v0.1.6 while the repo is at 0.1.11 (pyproject/__init__:5 | Not in challenge set; derived. Docs name code (file paths, flags) but the drift-detection MUST (CI name-existence lint OR code-side back-reference) is not evidenced, and CLAUDE.md carries stale v0.1.6 version labels naming behavior at an ol — FIXED 2026-06-07: name-existence lint = the PUBLIC_API.md↔__all__ pin test (test_public_api_doc_pin); stale v0.1.6 labels in CLAUDE.md made version-agnostic |
| DOC-10 | ✅ | FEEDBACK.md §1 Process (FEEDBACK.md:25-34) defines OPEN → SHIPPED/DEFERRED/WONTFIX/MOVED; §2 holds PAPER-01 with a metadata table (Status/Severity/Submitter/Submitted, FEEDBACK.md:42-48). do | Upheld. Consumer-facing FEEDBACK (PAPER-01, 🟡, lifecycle) is cleanly separated from internal posture (the conformance ledger is the only inprogress file). [verify-upheld] |
| DOC-11 | N/A | docs/inprogress/ holds only MGF_STANDARDS_CONFORMANCE.md — a perpetually-living conformance ledger, not a scope-complete tracker. No fully-closed tracker sitting un-archived; no docs/archive | Not in challenge set; derived. DOC-11's archival signal applies to completed trackers; the one inprogress file is an always-living ledger, so there is nothing to archive. N/A. |
| DOC-12 | ✅ | In-repo cross-refs are relative: STARTHERE.md:71-77 ([README.md](README.md), [CHANGELOG.md](CHANGELOG.md), [DEPS.md](DEPS.md), [docs/inprogress/MGF_STANDARDS_CONFORMANCE.md](...)); README.md | Upheld. Relative links for in-repo cross-refs, absolute only for genuinely cross-repo targets, hierarchical headings, and src/...:path form are all satisfied. [verify-upheld] |
| DOC-13 | ✅ | FEEDBACK.md:7-12 routes sibling-specific issues HERE and federation-wide to mgf-common/FEEDBACK.md; FEEDBACK.md:14-17 states local-per-repo PAPER-NN numbering with a federation cross-referen | Upheld. Repo-scoped FEEDBACK with sibling-vs-federation routing, local numbering, MOVED-with-redirect discipline described, and demonstrated by PAPER-01's filing note. [verify-upheld] |
| DOC-14 | N/A | No MGF_ADOPTION.md at docs/inprogress/ or docs/ (ls docs/inprogress shows only MGF_STANDARDS_CONFORMANCE.md). The project is a federation sibling (README.md:5 'A sibling of mgf-common'). | Not in challenge set; derived. ADP-04 carve-out: federation siblings do NOT maintain MGF_ADOPTION.md — their adoption relationship lives in mgf-common's federation_roadmap.md + their own CHANGELOG. N/A by shape. |
| DOC-15 | ✅ | docs/inprogress/MGF_STANDARDS_CONFORMANCE.md exists at the CFM-01 canonical path (ls docs/inprogress). README.md:7 declares 'Conformance: L2 ... Tracker: docs/inprogress/MGF_STANDARDS_CONFOR | Upheld for the presence+link+level MUST: file present at canonical path, README links it AND declares L2 in the same place. (Internal per-rule completeness is CFM-03's province, not this presence verdict — and was not opened per task constr |
| DOC-16 | ✅ | DEPS.md at repo root: §1 'What mgf-test-supervisor depends on' with a dep table incl. window/tier/dev-vs-runtime (DEPS.md:22-32); §2 'Who depends on mgf-test-supervisor' rostering every mgf- | Upheld. Repo-root bidirectional manifest with both §1 depends-on and §2 depended-on, plus a survey method correctly adapted to dev-only CLI/JSONL coupling rather than import sites. [verify-upheld] |
| DOC-17 | ✅ | FEDERATION.md:1-12 is a pointer stub: 'The federation contract is not maintained here ... Read the contract at mgf-common/FEDERATION.md ... Per DOC-17, siblings and consumers link here rathe | Upheld. For a non-mgf-standard project, FEDERATION.md is a pointer to the canonical contract and not a maintained copy, citing DOC-17 explicitly. [verify-upheld] |
| DOC-18 | N/A | DOC-18 (ripple rule) is a same-commit propagation discipline over coupled surfaces. The schema-alignment coupling (TestRecord/MARKER_TIER/SCHEMA_VERSION ↔ mgf.common.testing) IS pinned by te | Not in challenge set; derived. The mechanizable couplings this project owns (the two-sided schema pin) are wired; the rule's standards-doc/registry obligations belong to mgf-standard/mgf-common, not this sibling. Substantively honored;  |
| DOC-19 | ✅ | Root LESSON_LEARNED.md exists (ls -la repo root). Append-only header cites DOC-19 + template (LESSON_LEARNED.md:1-6), newest-first, one dated entry '2026-06-07 — File seeded (DOC-19 adoption | Upheld. DOC-19 (MUST since v2.21; DOCUMENTATION.md:44 + §2.0.1:167) requires the file to exist; a seeded, correctly-formatted file with no real lessons yet is explicitly conformant. Presence bar met. [verify-upheld] |

### OPERABILITY

| Rule | Status | Evidence | Notes |
|---|---|---|---|
| OP-01 | ✅ | src/mgf/test_supervisor/__main__.py:175 `--version` → `version=f"mtest {__version__}"` (0.1.11). That is the bare-version anti-pattern OP-01 names: it returns only the package version — no g | OP-01 (applies to all) MUST return RICH version: package version + git commit SHA + active environment label + load-bearing runtime info (Python version, OS/arch). `mtest --version` returns only `mtest 0.1.11`. The literal MUST is unmet — t — FIXED 2026-06-07 (0.1.13): mtest --version now rich (version+commit+python+platform+exec); lazy _VersionAction; pinned by test_version.py |
| OP-02 | ✅ | src/mgf/test_supervisor/self_check.py:64-122 `run_self_check` + __main__.py:363-370 `_cmd_self_check` (exposed as `mtest --self-check`). Check 0 verifies the supervisor imports its own modul | OP-02 requires a self-diagnostic command that probes the app's OWN state (distinct from a host-doctor), emitting a pass/fail checklist with pointers on failure, so 'is the app's own state the problem?' has a one-command answer. `--self-chec |
| OP-03 | ✅ | pyproject.toml:62-65 — Homepage / Issues / Changelog all point at the real repo `https://codeberg.org/magogi-admin/mgf-test-supervisor` (no `<placeholder>`). No `--help` footer / CLI-error U | OP-03 MUST: pyproject URLs and every CLI-printed URL resolve to the real repo/docs/tracker; CI MUST verify (HTTP-HEAD lint OR at minimum a no-`<placeholder>` grep). The URLs are real and consistent. The CI URL-resolve / no-placeholder lint  |
| OP-04 | ✅ | tests/unit/test_version_in_sync.py:23-41 pins `pyproject.toml::version` (0.1.11, pyproject.toml:3) to `__init__.py::__version__` (0.1.11, src/.../__init__.py:51) and runs in the per-version  | OP-04's MUST is that headline facts in README/STARTHERE match reality. They do, and the most error-prone fact (the version, which the CHANGELOG records was wrong 0.1.0-0.1.2) is mechanically pinned by a CI-enforced test. The CI test-count/p |
| OP-05 | N/A | No app-runtime config exists: dependencies = [] (pyproject.toml:46), CLI is argparse-only (__main__.py:166-237), no MgfSettings. Per the CONFIGURATION-is-N/A carve-out, adding a runtime MgfS | OP-05 MUST: a running app's active configuration is inspectable via `<app> explain` (secrets redacted). This supervisor has no app-runtime configuration to introspect — its only 'config' is per-invocation CLI flags (echoed by `_print_select |
| OP-06 | N/A | The supervisor has no runtime logging pipeline — per the OBSERVABILITY/LOGGING carve-out it is output-side only. Its run artefacts (run.jsonl, summary.md, failures/*.txt) live under `.gates/ | OP-06 MUST: recent LOGS are accessible without source-tree path knowledge (CLI `<app> logs` tails the rotating log file). This tool emits no rotating runtime log — it has no logging pipeline (LOGGING carve-out). The nearest analogue, the ru |
| OP-07 | ✅ | supervisor writes a self-contained per-failure diagnostic bundle for every failure under `.gates/last-run/failures/<test_id>.txt` — pytest stdout/stderr, traceback, durations, environment fi | OP-07's intent: one command produces a single attachable artefact for a bug report (redacted config + last N log lines + crash reports + doctor output + system info). The supervisor produces exactly this per failure — a self-contained `.txt |
| OP-08 | ✅ | State lives under `.gates/last-run/` (run.jsonl append-only; failures/*.txt — one per failing test; junit-NNNN.xml per chunk) per README.md:104-117. `.gates/last-run/` is overwritten each ru | OP-08 (applies to all) MUST: state directories have BOUNDED growth with a DOCUMENTED retention policy (size cap, age cap, or generational rotation). The `.gates/` layout is documented (README §State files) but no retention discipline is sta — FIXED 2026-06-07: README 'Retention (OP-08)' subsection documents the bounded-by-design .gates/ policy (last-run overwritten, durations rolling-5, quarantine sliding-window, no cross-run accumulation) |
| OP-09 | N/A | Service-only rule (OPERABILITY rules box 'Applies to: service'). mgf-test-supervisor is a stdlib-only CLI library, not a deployed service — no `environment=production`, no listener, no `vali | OP-09 applies only to service-shape projects (a production config validator that fail-fast refuses dev-shaped values before a listener opens). This is a user-facing CLI library with no deployment/listener/production-config surface. N/A by t |
| OP-10 | N/A | Service-only rule. No deployable image/manifest — it is published as a Python wheel/sdist to a package index (pyproject.toml:84-91 hatchling build; CHANGELOG/CI reference PyPI publish), not  | OP-10 applies only to service-shape deployable artefacts (no `image:latest` in production manifests; tag with semver + git SHA; rollback runbook). This library ships as a versioned wheel, not a deployed image; package-version rollback is vi |
| OP-11 | N/A | Service-only rule. No alerting surface — no Prometheus rules, no alertmanager, no paging path; a CLI test runner has no on-call/runbook story. | OP-11 applies only to service-shape projects with an alerting + paging story (every alert reaches a human + links a runbook). A single-user CLI library emits no alerts and has no paging path. N/A by the service-only scope. |
| OP-12 | N/A | Service-only rule. No backup/restore surface — the supervisor persists only ephemeral, regenerable per-run state under `.gates/` (README.md:104-117); there is no S3/R2/GCS production data st | OP-12 applies only to service-shape projects with a real backup target (restore drill against real S3/R2/GCS before go-live, quarterly cadence). This library holds no durable production data — `.gates/` is regenerated each run and is `.giti |

### DEPLOYMENT

| Rule | Status | Evidence | Notes |
|---|---|---|---|
| DEP-01 | N/A | DEPLOYMENT.md:7-18 scopes the standard to 'stateful web-service consumer applications'; lines 20-21 declare 'Federation libraries (no runtime)' out of scope. DEP-01 'Applies to: service' (DE | Premise does not bind: there is no cloud infrastructure. This is a library with no deployed runtime; IaC has nothing to declare. |
| DEP-02 | N/A | DEPLOYMENT.md:42 DEP-02 'Applies to: service'; scope clause DEPLOYMENT.md:20-21 excludes federation libraries. No ansible/, chef/, salt/, Dockerfile build-pipeline for a production VM exists | No production VM or container state exists to express as config-as-code; the project ships as a wheel, not a server image. |
| DEP-03 | N/A | DEPLOYMENT.md:43 DEP-03 'Applies to: service' — about deploy-time artefact immutability for a running service. DEPLOYMENT.md:20-21 excludes federation libraries. mgf-test-supervisor has a uv | Premise (a release artefact deployed to running production servers) does not exist for a library; immutable-release-artefact discipline is governed for libraries by RELEASING/PACKAGE_DISTRIBUTION, not DEP-03. |
| DEP-04 | N/A | DEPLOYMENT.md:44 DEP-04 'Applies to: service'; §8/§4.4 (DEPLOYMENT.md:322-345) frame this as production-service secrets (DB creds, TLS keys, OAuth) stored in Ansible Vault/KMS for a deployed | No production deployment, therefore no production secrets to manage. SC-01 (repo-secret hygiene) is the binding rule for a library, not DEP-04's deploy-time vault requirement. |
| DEP-05 | N/A | DEPLOYMENT.md:45 DEP-05 'Applies to: service'; the rule governs deploy/backup/restore/rollback scripts in deploy/scripts/ (DEPLOYMENT.md:185-191, 347-389). No deploy/ directory exists (ls co | No deploy/backup/restore scripts exist because there is no deployment; the premise (environment-explicit deploy commands) does not bind a library. |
| DEP-06 | N/A | DEPLOYMENT.md:46 DEP-06 'Applies to: service'; rollback shapes (blue/green, symlink-swap, snapshot-restore at DEPLOYMENT.md:394-429) presuppose a running production service. Library carve-ou | No production deploy to reverse; reversible-deploy/rollback-runbook premise does not bind a library with no runtime. |
| DEP-07 | N/A | DEPLOYMENT.md:47 DEP-07 'Applies to: service'; §3 (DEPLOYMENT.md:146-217) requires a top-level deploy/ at a CONSUMER application root, explicitly NOT a library. DEPLOYMENT.md:199-209 ties de | The deploy/ directory shape is mandated only for web-service consumer applications; a federation-sibling library is the wrong shape, so the rule's premise does not bind. |
| DEP-08 | N/A | DEPLOYMENT.md:48 DEP-08 'Applies to: service'; requires deploy/docs/slo.md, burn-rate alerts, paging channels for a running production service (DEPLOYMENT.md:469-501). Audit carve-out: obser | No production runtime to make observable end-to-end; SLO/alert/paging premise does not bind a library that merely emits JSONL artefacts. |
| DEP-09 | N/A | DEPLOYMENT.md:49 DEP-09 'Applies to: service'; governs DNS records and auto-renewed TLS certs for a deployed service (DEPLOYMENT.md:502-533). The supervisor has no DNS records, no TLS endpoi | No DNS or TLS infrastructure exists for a library with no served endpoint; premise does not bind. |
| DEP-10 | N/A | DEPLOYMENT.md:50 DEP-10 'Applies to: service'; requires deploy/docs/first-production-cut.md documenting green-field cloud provisioning (DEPLOYMENT.md:535-558). No deploy/ directory and no pr | There is no green-field production environment to provision; the first-production-cut runbook premise does not bind a library. |
| DEP-11 | N/A | DEPLOYMENT.md:51 DEP-11 'Applies to: service'; requires deployability to >=2 environments (prod + staging/dev) from shared IaC + config-management (DEPLOYMENT.md:560-596). No IaC, no environ | No deployable environments exist for a library; the multi-environment-from-same-code premise does not bind. |

### PRESENTATION_LAYER

| Rule | Status | Evidence | Notes |
|---|---|---|---|
| PR-01 | ✅ | src/mgf/test_supervisor/*.py imports are stdlib-only (argparse, json, os, sys, time, pathlib, dataclasses, typing, subprocess, signal, re, shutil, tempfile, contextlib) — grep -rnE over src/ | PR-01 has two clauses: (a) the SDK MUST NOT import any UI framework — substantively MET (zero such imports anywhere under src/mgf/test_supervisor/); and (b) 'The rule MUST be enforced mechanically via import-linter (or equivalent).' Clause — FIXED 2026-06-07: clause (a) no-UI-import already held; clause (b) mechanical enforcement now met by the .importlinter UI-forbid + lint-imports CI gate (this session's CI batch). |
| PR-03 | N/A | find src -type d shows only src/mgf/test_supervisor/ (a single flat package); no src/<app>/{core,view,ui/<framework>}/ and no presentation/<framework> layout. project name is the supervisor  | PR-03 binds 'An app repo with multiple UIs.' This is a pure tool/SDK sibling, not an app repo, and has no second UI consumer. The standard §8.2 names mgf-test-supervisor explicitly: 'federation libraries with no multi-UI consumer ... PR-02. |
| PR-04 | N/A | No core/view/ui layer hierarchy exists to enforce (find src -type d = single package). .woodpecker.yml:20 confirms no import-linter layer contracts. No app repo, no multiple UIs. | PR-04 mandates import-linter contracts enforcing 'The layer hierarchy' — the core/view vs ui/<framework> split of PR-03. With no app repo and no multi-UI layer hierarchy in existence (PR-03 is N/A), there is no layer hierarchy for PR-04 to  |
| PR-05 | N/A | Only one UI exists: a single argparse CLI surfaced via src/mgf/test_supervisor/__main__.py (console scripts mgf-test-supervisor / mtest, pyproject.toml:69-71). There are no ui/<framework>/ a | PR-05 ('each ui/<framework>/ adapter MUST consume view/ only, never another ui/<other>/') is only meaningful when ≥2 UI adapters exist — the standard itself says so in §6 ('sibling-UI isolation is only meaningful when ≥2 UIs exist'). With a |
| PR-07 | N/A | mgf-test-supervisor is a single-UI argparse tool with zero additional UI consumers (no app repo, no core/view/ui or presentation/<framework> layout — find src -type d = one package). Standar | PR-07's binding MUST ('A sibling at L1+ WITH a UI consumer MUST have a PR — PRESENTATION_LAYER section in MGF_STANDARDS_CONFORMANCE.md') is conditioned on having a UI consumer; this sibling has none, so the mandatory-section premise does no |

### AGENTS

| Rule | Status | Evidence | Notes |
|---|---|---|---|
| AG-01 | ✅ | AGENTS.md (37 lines) is the thin pointer: lines 3-9 'do not edit it; project-specific agent notes belong in this project's CLAUDE.md' + line 9 'Run mgf-common agents'. `diff AGENTS.md /home/ | AGENTS.md exists at repo root, is the thin pointer, carries no inline briefing, and is byte-identical to the mgf-common federation template. Project-specific notes live in docs/claude/CLAUDE.md. Rule fully met. [verify-upheld] |
| AG-02 | ✅ | AGENTS.md:9 'Run mgf-common agents and do exactly what it prints'; AGENTS.md:36 'One message for the whole federation; no per-project variant.' docs/claude/CLAUDE.md:10 routes canonical brie | The repo points at the single source (`mgf-common agents`) and keeps project-specific content in CLAUDE.md, not AGENTS.md. The canonical briefing is the CLI output, not duplicated here. Met. [verify-upheld] |
| AG-03 | ✅ | .gitmessage lines 9-10 hard-code both trailers (Signed-off-by: Bassam Alsanie <bassam@magogi.org> + Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>). `git log -10` shows | AG-03's literal MUST is that agent-authored commits include BOTH signing trailers; verified present on every inspected commit. Recent commits use the canonical bassam@magogi.org identity; .gitmessage enforces both trailers going forward. Th |
| AG-04 | ✅ | FEEDBACK.md exists: §1 Process (lines 25-35) 'Any consumer hitting friction MUST file a PAPER-NN under §2'; §2 active paper PAPER-01 with full repro. CLAUDE.md:173-174 directs friction to `m | The repo ships the FEEDBACK paper channel and documents filing reusable friction as a paper rather than burying it in CLAUDE.md gotchas. The FEEDBACK lifecycle is present and used. Met. [verify-upheld] |
| AG-05 | N/A | Behaviour rule (agents MUST verify memory claims before acting). No checkable repo artifact; runtime/self-enforcement per standard §9. | Not part of this refute pass; left unchanged. Pure agent-behaviour rule with no repo-level artifact to audit. |
| AG-06 | N/A | Runtime/harness enforcement (permission prompts on Bash/MCP per standard §9). Not a code rule. | Not part of this refute pass; left unchanged. Runtime-enforced behaviour rule, no repo artifact. |
| AG-07 | N/A | Self-enforcement; runtime task-list reminders per standard §9. No repo artifact. | Not part of this refute pass; left unchanged. Runtime-enforced behaviour rule. |
| AG-08 | N/A | Self-enforcement; runtime auto-memory rules per standard §9. No repo artifact. | Not part of this refute pass; left unchanged. Runtime-enforced behaviour rule. |
| AG-09 | N/A | Review-only behaviour rule (verify sibling versions against Codeberg registry). No repo artifact. | Not part of this refute pass; left unchanged. Agent-behaviour rule, review-only. |
| AG-10 | N/A | Review-only behaviour rule (standards drift → file a PAPER). No repo artifact. | Not part of this refute pass; left unchanged. Agent-behaviour rule, review-only. |
| AG-11 | ✅ | FEEDBACK.md header lines 7-12 codify routing exactly: 'mgf-test-supervisor-specific → file HERE'; 'Federation-wide (cross-sibling patterns, standards proposals) → file in mgf-common/FEEDBACK | AG-11 has a checkable repo artifact: the target-project routing convention. This repo's FEEDBACK.md documents correct target routing (sibling-specific here, cross-cutting to mgf-common) and PAPER-01 demonstrates what-hurts/why/evidence/sugg |
| AG-12 | ✅ | `mgf-common agents --project` reads docs/claude/CLAUDE.md (falling back to AGENTS.md). Repo ships docs/claude/CLAUDE.md (175 lines, dense project lookup); AGENTS.md:20-22 points agents at do | The project-scoped briefing content exists at docs/claude/CLAUDE.md (the location `--project` reads) and mgf-common is installed as a dep, giving the repo the uniform `mgf-common agents --project` surface. The repo's responsibility — ship t |
| AG-13 | ✅ | CLAUDE.md:120-133 (DEPS) declares mgf-common as a DEV-only alignment-contract dep, not edited here. FEEDBACK.md routing (lines 7-12) sends library-change requests to the target library's FEE | This repo does not edit mgf-common (it only mirrors the alignment contract and pins a dev dep). Change requests are routed via FEEDBACK papers to the owning library. The 'only the supervisor changes a library; others file a request' discipl |
| AG-14 | ✅ | CLAUDE.md:143-147 'Any change to TestRecord shape, MARKER_TIER, or SCHEMA_VERSION MUST land in BOTH this repo and mgf.common.testing in the SAME commit/wave. Pinned by tests/unit/test_alignm | The repo documents and mechanically pins its coupled surfaces (cross-repo schema alignment via paired alignment tests — verified to exist — plus the DEPS §2 consumer ripple walk), satisfying the same-change propagation MUST. Met. [verify-up |
| AG-15 | N/A | Charter grants license, not a checkable artifact (standard §9 / §10). Review-only. | Not part of this refute pass; left unchanged. Empowerment-charter rule with no repo-level artifact beyond the corpus itself. |
| AG-16 | ✅ | AG-16 MUST: 'depend on mgf-common[standards]'. pyproject.toml declares `mgf-common>=0.41,<0.47` as a plain dev dep (line 59) with NO [standards] extra — `grep -c standards pyproject.toml` => | Not part of the supplied refute set, but the literal AG-16 MUST (declare mgf-common[standards]) is unmet: the repo pins plain `mgf-common`, not `mgf-common[standards]`. Flagged ⏳ pending an explicit carve-out; the TS-23 stdlib-only mandate — FIXED 2026-06-07: a separate [standards] extra declares mgf-common[standards]>=0.46 (corpus resolvable to agents via .[standards] with the Codeberg index; kept OUT of [dev] so CI pip-install from pypi.org has no regression) |
| AG-17 | ✅ | docs/memory/MEMORY.md present (the project memory index). |
| AG-18 | ✅ | my_stuff/ git-ignored + .githooks/prepare-commit-msg present (auto-adds the Signed-off-by trailer). |
| AG-19 | N/A | no runtime auto-memory store for this project yet (~/.claude/projects/<slug>/memory/ absent) — nothing to VCS-track; binds only once such a store exists. |
| TM-01 | ✅ | UTC at boundaries — uses tz-aware `datetime`/UTC. |
| TM-02 | ✅ | ISO-8601/RFC-3339 wire format for datetimes. |
| TM-03 | N/A | no duration measurements with a wall clock (timeouts are not timed spans). |
| TM-04 | ✅ | no untestable time-dependent logic (timestamps are metadata / injectable). |
| TM-07 | N/A | UTC only; no IANA timezone-name usage. |
| TM-08 | N/A | no async. |
| PF-01 | N/A | no performance budgets / perf tests. |
| PF-02 | N/A | no performance budgets / perf tests. |
| PF-03 | N/A | no performance budgets / perf tests. |
| PF-04 | N/A | no performance budgets / perf tests. |
| PF-05 | N/A | no performance budgets / perf tests. |
| PF-07 | N/A | no performance budgets / perf tests. |
| PF-08 | N/A | no performance budgets / perf tests. |
| OB-01 | N/A | no owned observability surface — consumes `mgf.common.observability` (OB rules bind the owner). |
| OB-02 | N/A | no owned observability surface — consumes `mgf.common.observability` (OB rules bind the owner). |
| OB-03 | N/A | no owned observability surface — consumes `mgf.common.observability` (OB rules bind the owner). |
| OB-04 | N/A | no owned observability surface — consumes `mgf.common.observability` (OB rules bind the owner). |
| OB-05 | N/A | no owned observability surface — consumes `mgf.common.observability` (OB rules bind the owner). |
| OB-07 | N/A | no owned observability surface — consumes `mgf.common.observability` (OB rules bind the owner). |
| OB-08 | N/A | no owned observability surface — consumes `mgf.common.observability` (OB rules bind the owner). |
| OB-09 | N/A | no owned observability surface — consumes `mgf.common.observability` (OB rules bind the owner). |
| OB-10 | N/A | no owned observability surface — consumes `mgf.common.observability` (OB rules bind the owner). |
| OB-11 | N/A | no owned observability surface — consumes `mgf.common.observability` (OB rules bind the owner). |
| NM-01 | ✅ | distribution name is hyphenated (NM-01). |
| NM-02 | ✅ | dotted import namespace `mgf.<sibling>` (NM-02). |
| NM-03 | ✅ | Codeberg slug hyphenated (NM-03). |
| GUI-01 | ✅ | imports no Qt at module level (GUI-01). |
| GUI-02 | N/A | no GUI (non-GUI library/CLI). |
| GUI-03 | N/A | no GUI (non-GUI library/CLI). |
| GUI-04 | N/A | no GUI (non-GUI library/CLI). |
| GUI-05 | N/A | no GUI (non-GUI library/CLI). |
| GUI-06 | N/A | no GUI (non-GUI library/CLI). |
| GUI-07 | N/A | no GUI (non-GUI library/CLI). |
| GUI-08 | N/A | no GUI (non-GUI library/CLI). |
| GUI-09 | N/A | no GUI (non-GUI library/CLI). |
| GUI-10 | N/A | no GUI (non-GUI library/CLI). |
| REL-10 | ✅ | federation member; participates in cohort-walk releases on a mgf-common pin break. |
| REL-11 | ✅ | released via the Phase A/B cohort-release flow. |
| REL-12 | N/A | binds the cohort Phase-A *agent's* pytest-denial handling, not a released sibling's code. |
| REL-13 | ✅ | releases pass the federation consistency gate (`mgf-fed registry --check`). |
| FB-05 | ✅ | cross-repo feedback flows through the `pending-feedback/<target>.md` outbox + the supervisor relay (`mgf-fed feedback`), never a direct edit (FB-05). |


---

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

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