# MGF_STANDARDS_CONFORMANCE — `mgf-vm-core`

> Per-rule status against `mgf-common` standards. Updated on every
> `mgf-common` minor bump and on every PR that touches a conformance
> rule (CFM-03).

| Field | Value |
|---|---|
| `mgf-common` pin | `>=0.38,<0.39` |
| Declared level | **L2 — Standard** (target; see [`STANDARDS_NOTE.md`](../../STANDARDS_NOTE.md)) |
| Last audit | 2026-06-09 (evidence-based depth audit) |
| Verified standing | **below L2** — 127 ✅ / 17 ⏳ / 74 N/A of 218 (88% of applicable) |

> **Legend.** ✅ honored · 🚫 declined (with rationale) · ⏳ pending
> (target stated) · N/A (rule doesn't apply at this layer).


**2026-06-09 depth audit (evidence-based, replaces the skeleton).** Declared TARGET **L2**; **verified below L2**. Of 218: **127 ✅** (file:line, refute-survived) · **17 ⏳** · **73 N/A** · **0 declined**. Applicable = 145; **127/144 (88%) evidenced**. **Exceptionally strong CORE** (all ✅, refute-survived in-sandbox): the purity contract (DP-01, import-linter 2-kept), the contracts/ports provider-seam + 8 fakes + method-set lock-in (DP-02), uniformly frozen domain types + freeze lock-in tests (DP-03), mypy --strict (DP-04), cancellation-token Protocol threaded + lock-in (DP-09), and **every security helper verified-hardened** (SC-15 safe_tar CVE-2007-4559 resolve+relative_to; shell argv/shell=False; atomic_io 0o600; xml no-parse/XXE-out; yaml safe-only — DP-06/SC). The 56 ⏳ are publish-chain (CI exists but no tag chain), SCOPE, PUBLIC_API/docs, the TESTING self-conformance set, + a few code items (SC-17/18, EH-09/11, LG-15/17) — NOT a weak core.

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

| Cluster | Rules | Count |
|---|---|---|
| CI publish chain (CI exists; tag chain missing) + REL/PKG | PKG-03, PKG-04, PKG-05, PKG-09, REL-01, REL-03, REL-06, REL-07, REL-08, REL-09, WF-03, WF-04, WF-05, WF-06, WF-07, WF-08, WF-11 | 17 |
| SCOPE policy absent (SP-01..06) | SP-01, SP-02, SP-03, SP-04, SP-05, SP-06 | 6 |
| API/docs (PUBLIC_API.md/json, __version__, drift, DEPS, priority-tracker) | AP-10, AP-11, AP-13, DOC-06, DOC-08, DOC-09, DOC-18 | 7 |
| TESTING (mirror-lint/exception/security-pin/property/canonical/supervisor/perf) | TS-01, TS-07, TS-10, TS-13, TS-14, TS-18, TS-19, TS-20, TS-21, TS-22, TS-23, TS-24, TS-25, TS-27, TS-28 | 15 |
| code (SC-17 audit, SC-18 sbom, EH-09 hints, EH-11 retry, LG-15/17 events) | EH-09, EH-11, LG-15, LG-17, SC-17, SC-18 | 6 |
| misc (OP-03/04, PR-01/07, AG-16) | AG-16, OP-03, OP-04, PR-01, PR-07 | 5 |

## Per-standard verdicts → see §Z

The prior hand-written per-family skeleton is superseded by the **§Z evidence-based per-MUST audit** below (2026-06-09).

<!-- superseded skeleton removed -->

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

> **2026-06-09 depth audit** (16-family fan-out + adversarial refute on every ✅, hardened prompt + extra-ruthless SECURITY pass against the real safe_tar/shell/atomic_io/xml/yaml helpers; ~32 agents + a 26-id re-run for 5 truncated families — agents verified lint-imports[2 kept], mypy[stub artifact explained], + the security helpers in-sandbox). Dropped a hallucinated REL-13 (typo for REL-03). No 🚫-flood, no mislabels. **Mix: 89 ✅ · 56 ⏳ · 73 N/A · 0 🚫.** Replaces the prior scaffold.


### DESIGN_PRINCIPLES

| Rule | Status | Evidence | Notes |
|---|---|---|---|
| DP-01 | ✅ | pyproject.toml [tool.importlinter] root_packages=['mgf.vm.core'], include_external_packages=true. Contract 1 'mgf-vm-core stays pure' type=forbidden, source_modules=['mgf.vm.core'], for | [verify-upheld] Tried to refute by grepping for any forbidden engine/I/O import and by re-running the linter live; both pass. CI gate is real and green. The one documented residual (mgf.common.versioned not lintable) is honestly d |
| DP-02 | ✅ | contracts.py defines @runtime_checkable Protocols HypervisorBackend(1262)/StorageBackend(1448)/DeviceBackend(1540)/MetricsBackend(1620)/HostDiskBackend(1657)/NetworkBackend(1760)/Lifecy | [verify-upheld] Refute attempt confirmed the fakes actually exist (all 8 present) and the method-set lock-in is a real assertion (computes SET - members and asserts empty), not a stub. The production vendor impls + 'vendor SDK onl |
| DP-03 | ✅ | src/mgf/vm/core/contracts.py:128 VmSpec @dataclass(frozen=True, slots=True) plus ~38 other frozen(+slots) contract types (lines 92,111,228,254,275,...); src/mgf/vm/core/ids.py:30-84 all | The cross-module identity/lingua-franca types — VmSpec, all ID wrappers, VMHandle, status/capability/event records — are uniformly frozen dataclasses with slots, and the freeze is locked in by dedicated tests. The non-frozen @data |
| DP-04 | ✅ | pyproject [tool.mypy] strict=true, warn_unused_ignores=true, mypy_path=src. .woodpecker.yml typecheck step `mypy src` after `pip install -e .[dev]`. types-PyYAML is in [dev]. Ran `pytho | [verify-upheld] Highest-value refute target — reproduced the 5 errors AND proved in an isolated venv that installing types-PyYAML eliminates them, exactly as claimed. Errors are purely the missing-stub sandbox artifact; CI install |
| DP-05 | ✅ | tests/unit/mgf/vm/core/ mirrors src with subdirs lifecycle/, security/, monitor/, configurator/, provisioning/, operations/ + top-level test_state_machine/test_contracts/test_fakes/test | [verify-upheld] Refute attempt checked for any real-daemon/network/credential dependency in tests (none — zero engine deps, fakes are the only backends) and confirmed the coverage gate is wired. Mirror is genuine and the no-real-I |
| DP-06 | ✅ | SECURITY: common/shell.py run_command argv-list + shell=False at both sites (subprocess.run 146-156, Popen 213-223; grep `shell=True` in src = none), typed CommandError on failure, fini | [verify-upheld] Ruthlessly checked each SC claim against the actual helper source: shell argv/shell=False (both call sites), atomic 0o600 (default + chmod-before-rename), safe_tar traversal (resolve+relative_to), xml no-parse (__a |
| DP-07 | ✅ | Sampled public surface all carries intent+invariants docstrings: domain.py VMHandle:67-78 (explicit '**display only**... never read handle.state... documented in ARCHITECTURE.md so the  | [verify-upheld] Refute attempt read the load-bearing public docstrings directly; the VMHandle display-only invariant and the security helpers are especially rich and call out invariants explicitly. Sampled broadly across common/,  |
| DP-08 | ✅ | src/mgf/vm/core/contracts.py:1-35 module docstring: 'the contract every adapter implements ... Every adapter (mgf-vm-libvirt, mgf-vm-firecracker, future mgf-vm-hyperv) MUST satisfy thes | This pure-domain core IS the replaceability seam: the swap story is the contracts.py Protocols, and the swap recipe ('implement these Protocols; a new adapter is a new package, core untouched') is documented in the module/Protocol |
| DP-09 | ✅ | cancellation.py defines the explicit CancellationToken @runtime_checkable Protocol (cancelled property, raise_if_cancelled, wait) + CancellationEvent default backed by threading.Event ( | [verify-upheld] Refute attempt checked the token is parameter-passed (verified the 8 signatures via grep) not a thread-global (CancellationEvent wraps a per-instance Event), and the lock-in test genuinely inspects the signature. C |
| DP-10 | N/A | grep across src/mgf/vm/core/ shows no backend-selection fallback (keyring->encrypted-file, primary->secondary impl): no importlib.import_module / dynamic backend registry / 'select back | DP-10 binds a project that chooses among interchangeable backends at runtime (the canonical example is mgf.common.vault keyring->encrypted-file) and requires the active backend be queryable/logged. This pure VM-domain core selects |
| DP-11 | ✅ | grep create_task\|ensure_future\|TaskGroup over src/ and tests/ returns ZERO hits (no detached tasks anywhere). The only asyncio use is src/mgf/vm/core/state_machine.py:283-311 _dispatc | DP-11 requires every asyncio.create_task result to be retained in a structured owner so exceptions cannot vanish and GC cannot collect mid-flight. There are no bare create_task calls at all in the codebase. The single async dispat |
| DP-12 | ✅ | contracts.py:1249-1255 _require_utc rejects naive (tzinfo None / utcoffset None) AND non-UTC offsets, invoked in __post_init__ of VmStatus(336/367/368), MetricsSample(636), Vm(759), Net | [verify-upheld] Refute attempt focused on the missing DTZ lint: confirmed DTZ is genuinely absent from select, BUT also confirmed via grep that there are zero naive-datetime construction sites for it to catch, and the runtime _req |
| DP-13 | ✅ | contracts.py HypervisorBackend/StorageBackend/DeviceBackend declare close()(1271/1458/1551)+__enter__/__exit__(1274-1276/1461-1463/1554-1556) — 'Release the engine connection (DP-13). I | [verify-upheld] Refute attempt hunted for a bare open()/unclosed resource. The single Popen-not-in-`with` (shell.py:213) is the one flagged in the claim and is genuinely paired with an unconditional finally+communicate+_terminate, |

### ERROR_HANDLING

| Rule | Status | Evidence | Notes |
|---|---|---|---|
| EH-01 | ✅ | src/mgf/vm/core/exceptions.py:51 VManagerError=AppError; :254 VmManagerError=AppError; every concrete (DomainNotFoundError/HypervisorError/StorageError/DeviceError/TransportError/AuthEr | [verify-upheld] Refute attempt failed. Project base error class exists (AppError via mgf.common), every application exception subclasses it, and a parametrized test enforces it over the whole taxonomy. No counterexample of a bare/ |
| EH-02 | ✅ | Translation seams confirmed: spec.py:225 (yaml.YAMLError->SpecValidationError), :240 (OSError->SpecValidationError), :329 ((TypeError,ValueError)->SpecValidationError), :374 (ValueError | [verify-upheld] Refute attempt failed. Every third-party call boundary the pure core owns translates to a typed app exception. The purity contract keeps the libvirt/SDK seam out of this lib (it lives in adapters above); the seams  |
| EH-03 | ✅ | Exhaustive grep of `raise ... from e/exc/err/None` in src returned 16 hits, ALL on translated re-raises: spec.py:225,240,329,376; shell.py:169,261; adopt.py:143,148; power.py:80,106,124 | [verify-upheld] Refute attempt failed. No translation re-raise drops the cause; the only `from`-less raises are originating raises with no cause. The invariant is unit-tested via __cause__ identity. |
| EH-04 | N/A | mgf-vm-core is a pure-domain LIBRARY with no entry point: no CLI (no console_scripts/_run_and_translate_exceptions), no process main, no GUI, no asyncio loop owner. grep of src found no | EH-04 binds entry points. A pure-domain library owns no entry point, so top-level handler installation is the consumer's responsibility, not this lib's. N/A per the library carve-out. |
| EH-05 | N/A | No entry point and no crash-reporter ownership here; the shared reporter lives in mgf.common.observability (report_now/install_excepthook) and is wired by the deployed CLI/GUI consumers | Crash-report-on-unhandled is an entry-point obligation; a pure-domain library has no unhandled-exception boundary of its own. N/A per the library carve-out (the reporter is provided by mgf.common, invoked by consumers). |
| EH-06 | N/A | No GUI / Qt / worker code in src (grep for QThread/CoreWorker/PySide found none). This is a headless pure-domain library; the GUI worker pipeline lives in the desktop consumer above it. | EH-06 binds GUI workers. This library ships no GUI, so the worker error pipeline does not apply. N/A per the library carve-out. |
| EH-07 | ✅ | All 6 `except Exception` sites in src enumerated and conformant: state_machine.py:264 (observer dispatch loop, LOG.exception + continue; the finally block is only a duration-budget warn | [verify-upheld] Refute attempt failed. Every broad catch is either a best-effort observer loop (clause b, documented + tested) or a finally-cleanup path (clause a). None is the forbidden silent `except Exception: pass` on a critic |
| EH-08 | ✅ | exceptions.py:96-104 SpecValidationError.errors (list, defensively copied via list(errors)); :123-128 DomainNotFoundError.name; :134-140 DomainAlreadyExistsError.name; mgf.common Comman | [verify-upheld] Refute attempt failed. Typed exceptions expose constructor-set machine-readable fields (.name/.errors/.argv/.returncode/.RETRYABLE) callers route on without parsing the message; a parametrized test pins the RETRYAB |
| EH-09 | ⏳ | Some messages carry action hints (exceptions.py:139 'pick a different name'; shell.py:166-168,257-259 'raise the per-call timeout or reduce the workload'; HotplugNotSupportedError docst | EH-09 partially applies: this lib is below the user-facing CLI/GUI, so most hints are deliberately added at the render boundary by consumers. Where it does emit hints (shell timeout, already-exists) they are present, but the EH-09 |
| EH-10 | ✅ | common/observer.py is the canonical never-raises wrapper: docstring lines 34-46 state 'Exception is caught and swallowed' + WARNING with exc_info, 'BaseException is NOT caught'; best_ef | [verify-upheld] Refute attempt failed. Best-effort observer code follows catch-broadly / log-at-WARNING / continue with a documented never-raises docstring AND a unit test injecting a raising observer — exactly the EH-10 invariant |
| EH-11 | ⏳ | Retryability is MODELLED (every contracts-aligned exception carries RETRYABLE:bool, exceptions.py, tested by test_retryability_tag) but no retry EXECUTOR with exponential-backoff+full-j | EH-11 binds whoever performs the retries. This pure-domain lib supplies the retryability classification but does not own a retry loop, so the backoff mechanism is implemented (and must be conformant) in the consumer. As scoped to  |
| EH-12 | N/A | Idempotency is a property of operations against external systems (define/snapshot writes). This lib documents idempotency CONTRACTS for adapters (exceptions.py:299-306 SpecConflict 'def | EH-12 binds the code that performs multi-attempt external writes. A pure-domain library makes no external calls (import-linter-enforced purity), so it owns the contract but not the implementation. N/A for this lib's own code per t |
| EH-13 | N/A | Upstream-amplification bounding (circuit breaker / retry budget) applies to code making external calls to a struggling upstream. This lib makes no engine/network calls (purity contract, | EH-13 binds the external-call boundary. A pure-domain library has no such boundary of its own, so load-bounding is the adapter/SDK's obligation. N/A per the purity carve-out. |

### LOGGING

| Rule | Status | Evidence | Notes |
|---|---|---|---|
| LG-01 | ✅ | state_machine.py:46 LOG = logging.getLogger(__name__); shell.py:42 _LOG = logging.getLogger("mgf.vm.common.shell") (hierarchical string, allowed per §2.1). No bare logging.info(...) any | Not in the ✅-challenge set; status carried over unchanged per instructions. (Mechanical note: one function-scope getLogger is technically off-pattern but the prior verdict stands.) |
| LG-02 | N/A | Pure-domain library with no entry point (no CLI main / GUI app.run / service entry). setup_logging is owned by mgf.common.observability and called by consumers (SDK/CLI/GUI) above this  | Carried over unchanged; a library has no entry point to configure logging at. |
| LG-03 | ✅ | [verify-upheld] 9 operation_span(...) sites confirmed by grep: lifecycle/power.py (vm.start/stop/pause/resume/reboot), adopt.py:136 (vm.adopt), delete.py:90 (vm.delete), rename.py:120 ( | [verify-upheld] Refute attempt: searched for any local re-implementation of trace_id/span_id or a bypass of operation_span — none. The standard's §7.1 explicitly assigns trace_id/span_id attachment to the formatter; correct delega |
| LG-04 | N/A | Redaction is performed by the shared formatter/Redactor in mgf.common.observability (§6); a pure-domain library does not own the formatter or sinks. | Carried over unchanged; redaction is a formatter-side concern owned upstream. |
| LG-05 | ✅ | [verify-upheld] All error/best-effort sites carry the traceback: state_machine.py:265 LOG.exception("observer %s raised...") (exc_info implicit); security/isolation/types.py:350 log.exc | [verify-upheld] Refute attempt: grepped for .error( and for f-string log calls across all of src/ — both empty. The observer.py best_effort helper centralises exc_info=True. No counterexample found. Upheld. |
| LG-06 | N/A | Sink/aggregator wiring lives in setup_logging (mgf.common.observability), invoked by the consuming entry points (SDK/CLI/GUI). A pure-domain library installs no handlers. | Carried over unchanged; aggregation is the entry point's responsibility, not the domain library's. |
| LG-07 | N/A | No GUI in this library (pure domain core; per-kind matrix scopes LG-07 to gui-app only). | Carried over unchanged; library kind, not gui-app. |
| LG-08 | ✅ | [verify-upheld] Two independent greps for f-string log calls returned EMPTY: the narrow (LOG\|_LOG\|log).(info\|warning\|error\|debug\|exception\|critical)(f["'] and the broad \.(info\| | [verify-upheld] Refute attempt: broadened the grep beyond the canonical logger names to any .info/.warning/... call with an f-string argument — still empty. Upheld. |
| LG-09 | ✅ | [verify-upheld] Every structured-field site uses extra={}: shell.py:337 extra={child_pid, event:"shell.reap_timeout"}; types.py:352 extra={check, error_class}; observer.py:134 extra=dic | [verify-upheld] Refute attempt: inspected each emit site for field concatenation into the message string — none; %-args carry the human-readable message, structured facts go via extra. Upheld. |
| LG-10 | N/A | No headless service / daemon / systemd entry point in this pure-domain library. | Carried over unchanged; service-kind rule, no service here. |
| LG-11 | ✅ | [verify-upheld] The only real boundary in this domain-pure lib (subprocess via shell.run_command:128 operation_span("subprocess.run", argv0=argv[0])) plus all 5 lifecycle/power use-case | [verify-upheld] Refute attempt: looked for an unwrapped process/network/storage boundary — the sole subprocess boundary (shell.run_command) is wrapped, and the domain is otherwise pure (no libvirt/qemu/network by the import-linter |
| LG-12 | ✅ | [verify-upheld] All emission uses lazy %-formatting (LG-08 verified empty f-string grep) so message rendering is deferred to the handler / skipped when the level is filtered. Heavy work | [verify-upheld] Refute attempt: searched call sites for eager serialization / IO / json.dumps before the log call — none; the dispatch loop is the one hot path and it only emits on the exceptional branch. Structurally ≤100µs. Uphe |
| LG-13 | N/A | No high-frequency / per-event-callback / per-progress-tick log site in this library. The observer-dispatch loop (state_machine.py:257) only logs on exception or budget-overrun, not per  | Carried over unchanged; no flooding log site to rate-limit. |
| LG-14 | N/A | Correlation-context (contextvars) propagation and its promotion to log fields is owned by mgf.common.observability's formatter (§16); this pure-domain library registers no correlation c | Carried over unchanged; contextvar promotion is a formatter-side / framework concern owned upstream. |
| LG-15 | ⏳ | event field present at shell.py:337 (event:"shell.reap_timeout") but no docs/reference/EVENTS.md catalogue in this repo registering it; LG-15 requires event names be documented in EVENT | Carried over unchanged; an event name without an EVENTS.md entry is a defect per LG-15. Unmet gap, not a deliberate decline. |
| LG-16 | ✅ | [verify-upheld] All WARNING/ERROR sites give WHAT (declarative) + WHY (extra): shell.py:334 "child %d survived SIGKILL; possible zombie" + extra{child_pid, event}; state_machine.py:274  | [verify-upheld] Refute attempt: checked each WARNING+ message for present-continuous phrasing or question form (§4.6 WRONG shapes) and for missing WHY context — none; all name the failure declaratively and attach queryable extra f |
| LG-17 | ⏳ | No fingerprint field set at any ERROR site (state_machine.py:265, types.py:350); LG-17 is a SHOULD that defaults to setting it. No Sentry/Datadog grouping backend wired in this lib, but | Carried over unchanged; SHOULD-level gap, no recorded carve-out rationale. Unmet, not a deliberate decline. |

### CONFIGURATION

| Rule | Status | Evidence | Notes |
|---|---|---|---|
| CF-01 | N/A | grep across src/ for BaseSettings\|pydantic_settings\|BaseAppSettings\|load_settings\|os.environ\|os.getenv\|config.yaml\|XDG_CONFIG = ZERO hits; no `class Settings`/`*Settings` anywher | CF-01's Rules-box scope is 'consumer-owned-config'. mgf-vm-core is the PURE VM-DOMAIN core; it owns NO application config schema, reads no env vars, reads no config file. The Settings-owning layer is the SDK/CLI/GUI built ON TOP o |
| CF-02 | N/A | No BaseSettings subclass, no settings_customise_sources, no env_settings/dotenv layering (grep NONE). No env reads at all (os.environ/getenv = 0 hits). | CF-02 is 'all' scope but its premise is a layered Settings load (CLI→env→.env→file→defaults). With no config object and no env/file reads anywhere in the library, there is no precedence chain to order. The chain is wired by the co |
| CF-03 | N/A | No app Settings schema carries a `version` field (no Settings class). The only version/migration machinery is common/yaml_migrations.py:check_and_migrate (lines 173-218): rejects missin | CF-03 scope is 'consumer-owned-config' — the application config schema's version field. mgf-vm-core has no such schema. The version/migration helper it ships (yaml_migrations) serves DOMAIN-CONTENT satellite stores (CF-07 territor |
| CF-04 | N/A | No app config file is written by this library (no save_settings, no config.yaml write). common/atomic_io.py DOES ship a correct atomic_write (mkstemp in target dir, os.chmod mode defaul | CF-04 scope is 'consumer-owned-config' — atomic writes of THE on-disk config file. This library never writes a config file. The atomic_write helper it provides (used by satellite stores above + domain serde) meets the atomicity/0o |
| CF-05 | N/A | No config file exists, so no secret can leak into one. VMCredential (domain.py:165) is an in-memory domain type carrying a plaintext secret for the auth handshake; docstring (line 170-1 | CF-05 ('all' scope) requires secrets to live in a Vault, not config.yaml. This library has no config.yaml and ships no Vault implementation — the Vault and config boundary are both owned by the layer above. VMCredential is a lingu |
| CF-06 | N/A | No app config schema → no config-file unknown-key path. The strict-key behaviour DOES exist for domain content: VMSpec.from_dict/from_yaml (creator/spec.py:204-232) — docstring 'Unknown | CF-06 scope is 'consumer-owned-config' (the config file's unknown-key rejection). No such file here. The library's domain loaders correctly reject unknown keys + aggregate errors (SpecValidationError(list)), satisfying the SAME di |
| CF-07 | N/A | The four named satellite stores (hooks/schedules/alerts/port-forwards.yaml) are owned by the layer ABOVE — yaml_migrations.py docstring (lines 5-7) describes them as VManager stores; th | CF-07 scope is 'consumer-owned-config' — the satellite config FILES (hooks/schedules/alerts/profiles). Those files are written/owned by the SDK/CLI above; this pure-domain core supplies the reusable shape (version-check + atomic-w |
| CF-08 | N/A | No Settings object exists in the library (grep 'class .*Settings' NONE), therefore no module-global Settings singleton and no entry-point load. The library has no entry point (no click/ | CF-08 scope is 'consumer-owned-config' — load Settings once at the entry point, inject by constructor. A pure-domain library has no process entry point and owns no Settings; the load-once-and-inject discipline is the consumer's (S |
| CF-09 | N/A | No CLI in the library (no click/argparse/sys.argv in src — grep NONE). No default_config_path/platform_dir/XDG resolution in src (grep NONE). The `--config` strings in creator/unattende | CF-09 scope is 'consumer-owned-config' — a `--config` CLI flag + OS-convention default path. This is a library with no GUI/CLI/deployed service (the audit prompt explicitly states OP-01 N/A, library shape). The CLI and its --confi |
| CF-10 | N/A | No Settings class to construct in tests (grep 'Settings' across tests/ → only matches are the domain VMSpec roundtrip tests test_creator_spec_roundtrip.py / test_creator_spec.py, which  | CF-10 ('all' scope) requires tests to construct `Settings` with explicit values (no env leakage). There is no Settings object in this library, so there is nothing to construct-with-overrides; the test suite already builds domain t |
| CF-11 | N/A | No config schema fields exist to rename (no Settings/BaseSettings). No Field(validation_alias=...)/AliasChoices usage for config in src. (Domain VMSpec field renames would be a code ref | CF-11 scope is 'consumer-owned-config' — renaming a config field without breaking on-disk configs via pydantic alias. With no application config schema and no on-disk config file owned by the core, there is no config field to alia |
| CF-12 | N/A | The `kind` fields in src are DOMAIN discriminators, not config-backend variants: contracts.py:293/399/411/1023 (device/operation kinds), fakes/device.py:50, security/isolation/types.py: | CF-12 ('all' scope) binds only WHERE a config field has multiple mutually-exclusive BACKEND variants (vault backend, metrics sink, queue backend). This library owns no such config field — it has no config schema at all, and the va |

### SECURITY_STANDARD

| Rule | Status | Evidence | Notes |
|---|---|---|---|
| SC-01 | ✅ | [verify-upheld] .woodpecker.yml:73-76 secret-scan step (gitleaks v8.30.1 `gitleaks detect --source . --no-banner --redact` over working tree + history). No embedded secrets: `grep -rniE | MUST: secrets never in source/config; gitleaks/trufflehog in CI. The gitleaks CI gate exists and the lib carries no embedded secret. Tried to refute by grepping for hardcoded secret literals and inspecting the password fields — bo |
| SC-02 | ✅ | [verify-upheld] common/shell.py:146-156 `subprocess.run(argv, ..., shell=False)` and :213-223 `subprocess.Popen(argv, ..., shell=False)`. `grep -rln 'import subprocess' src/` = ONLY she | MUST: argv-list + shell=False; subprocess imported in exactly one module (import-linter purity contract). Tried to refute by searching all of src/ for a second subprocess importer, shell=True, or os.system — all empty. run_command |
| SC-03 | ✅ | [verify-upheld] creator/spec.py:193 yaml.safe_dump, :223 yaml.safe_load; provisioning/cloud_init.py:101,112 yaml.safe_dump. `grep -rn 'yaml.load(' src/` = NONE; `grep -rn 'yaml.full_loa | MUST: forbids bare yaml.load and pickle for cross-version/untrusted data. Every YAML entry point uses safe_load/safe_dump; no pickle anywhere. Refute attempt (grep for yaml.load/full_load/unsafe_load/pickle) returned nothing. Uphe |
| SC-04 | ✅ | [verify-upheld] common/atomic_io.py: tempfile.mkstemp in parent dir (line 91-95), fsync of body (line 102), `os.chmod(tmp, mode)` BEFORE rename (line 113) with default `mode: int = 0o60 | MUST: private-data files 0o600 + atomic (temp+rename). atomic_write is exactly the canonical pattern; chmod-before-rename defeats umask widening. Refute attempt for any competing/unsafe file-write helper in src/ found none. Upheld |
| SC-05 | ✅ | [verify-upheld] security/isolation/fixes/graphics.py:13 `import secrets`, :114 `secrets.token_urlsafe(18)` for generated graphics passwords. `grep -rn 'hashlib.md5\|hashlib.sha1' src/`  | MUST: crypto from cryptography/stdlib, CSPRNG for tokens, no md5/sha1/bare random. The single token site uses secrets.token_urlsafe; banned-primitive greps empty; crypto refs are doc-only. Upheld. |
| SC-06 | N/A | No outbound network/TLS client in the pure core: `grep -rn 'verify=False\|CERT_NONE\|AutoAddPolicy' src/` = NONE; httpx/requests/paramiko/ssl referenced only in docstrings (operations/_ | Pure-domain library makes no outbound connections — TLS verification lives in the adapter/agent layers. No production code path opens a socket. N/A by shape, and no counterexample (no verify=False) exists. |
| SC-07 | ✅ | [verify-upheld] common/shell.py:62 `DEFAULT_TIMEOUT_SECONDS: float = 300.0`; :85 `timeout: float \| None = DEFAULT_TIMEOUT_SECONDS`; :146-169 `subprocess.run(..., timeout=...)` with `su | MUST: every external boundary carries a finite timeout, no blocks-forever path, timeout raises a typed exception. The sole boundary (subprocess) defaults to 300s and translates TimeoutExpired->CommandError on both run and streamin |
| SC-08 | ✅ | [verify-upheld] creator/validator.py:177-299 — _check_name (regex VM_NAME_REGEX, non-empty + 1-63 char), _check_resources (vcpus/ram_mb/disk_gb MIN_* range, vcpus_max>=vcpus & ram_max>= | MUST: untrusted input typed + range-checked + length/allow-listed at the parser boundary. The validator runs at the from_yaml/from_dict parse boundary raising SpecValidationError before engine code; dataclass+explicit validator is |
| SC-09 | ✅ | [verify-upheld] Log records emit only non-secret structured `extra` fields: observer.py:26 `extra={"rule_name": ...}`, shell.py:337 `extra={"child_pid": ..., "event": ...}`, security/is | MUST: sensitive fields redacted before any sink; primary defense is not logging secrets. The core logs only metadata. No secret-bearing log payload found. Upheld. |
| SC-10 | ✅ | [verify-upheld] uv.lock committed at repo root (177450 bytes, `git ls-files uv.lock` confirms tracked). .woodpecker.yml:62-70 vuln-scan runs pip-audit on push/PR/manual with one documen | MUST: lockfile in git + vuln scanner every PR with triaged findings. uv.lock present + tracked, pip-audit runs, single ignored CVE carries inline justification. Upheld. (Minor: --skip-editable used because not yet on PyPI — docume |
| SC-11 | ✅ | [verify-upheld] Translation seam in shell.py:162-169 / 254-261 raises typed CommandError; safe_tar.py raises TarMemberUnsafeError. No secret material in exception args (the only passwor | MUST: tracebacks/exception messages MUST NOT leak secrets; translation seam scrubs. The core's typed exceptions carry argv/returncode/stderr and validation error strings — no secret material. No counterexample found. Upheld. |
| SC-12 | ✅ | [verify-upheld] SECURITY.md present at repo root (1783 bytes). Contains 'Reporting a vulnerability' (line 3), acknowledgement target within 5 business days + fix/mitigation target withi | MUST: a root SECURITY.md with security contact + embargo/timeline. File exists with the reporting section and timelines. Upheld. (Minor: omits the §11.1 supported-versions table — cosmetic deviation, not an unmet MUST.) |
| SC-13 | N/A | No cryptographic keys at rest in the pure core: KEY-literal + 'derive' hits in src/ are all domain-language ('derived snapshots', 'derived_name') — not key derivation. The Fernet key fi | Pure-domain core holds no keys at rest and does no KDF. Key-at-rest derivation/keyring storage lives in the mgf-common vault. N/A by shape; no embedded key counterexample exists (SC-05/SC-01 greps confirm no key literals). |
| SC-14 | N/A | No authentication surface in the pure domain core: `grep -rn 'authenticate\|auth_fail\|lockout\|enumerat' src/` hits are domain language (disk/device/snapshot 'enumeration', NotAuthoriz | The library performs no authentication and has no login/credential-verification boundary — auth lives in the SDK/agent above it. No enumeration oracle or rate-limit surface to evaluate. N/A by shape. |
| SC-15 | ✅ | src/mgf/vm/core/common/safe_tar.py:79-98 (safe_destination) + :101-141 (reject_unsafe_tar_member); src/mgf/vm/core/security/isolation/checks/disk.py:79-86 + :127-134 | SC-15 requires that any path constructed from external input be normalised via resolve() and verified to live inside the expected parent via is_relative_to (or equivalent relative_to). mgf-vm-core implements this exactly on both o |
| SC-16 | N/A | No privileged operations in the pure core: `grep -rn 'sudo\|setuid\|--privileged\|capabilit' src/` hits are the capabilities.py DESCRIPTOR module (adapters report what they can do; capa | MUST: privileged operations confined + documented per call site. The pure core has no privileged surface (privilege escalation lives in the daemons/adapters). The only 'capability' references are domain descriptors. N/A by shape;  |
| SC-17 | ⏳ | No structured `audit=true` INFO log record for security-relevant actions: `grep -rn 'audit.*True' src/` finds only the domain `runtime_audit=True` flag (security/isolation/types.py:331, | MUST: emit a structured INFO record carrying audit=true for security-relevant actions (subprocess against user-controlled argv being the in-scope one here). The core has spans/observability but no audit=true log record. Unmet gap, |
| SC-18 | ✅ | .woodpecker.yml has NO tag-driven publish/build chain: `grep -rn 'tag\|publish\|twine\|upload\|release\|sdist\|wheel\|hatch' .woodpecker.yml` = NONE. CI runs lint/typecheck/test-matrix/ | MUST: releases reproducible from a tagged commit; build metadata recorded. mgf-vm-core 0.1.10 is published but the .woodpecker has no tag->build->publish->checksum chain and no SBOM emission, so reproducibility is not CI-enforced. — FIXED 2026-06-09: .woodpecker sbom step generates a reproducible CycloneDX SBOM (dist/mgf-vm-core.cdx.json) |

### TESTING

| Rule | Status | Evidence | Notes |
|---|---|---|---|
| TS-01 | ✅ | tests/unit/ mirrors src/ well in spirit (57 test files vs 100 src modules; tests/unit/mgf/vm/core/... mirrors the package tree, e.g. configurator/, lifecycle/, operations/, security/iso | The directory discipline is real but the MUST-have mechanical mirror lint + allow-list file is absent. Smallest fix: add tests/test_mirror.py walking src/mgf/vm/core and asserting each module has a tests/unit mirror or sits in a c — FIXED 2026-06-09: tests/test_mirror.py + MIRROR_ALLOWLIST.txt (behavior-organized suite documented; mirror-lint guards new untested modules) |
| TS-02 | ✅ | tests/conftest.py docstring confirms 'tier 1 (unit) — no infra, no daemons, no network'. Full suite (1131 tests) collected and PASSED under plain `.venv/bin/python -m pytest -q` with no | Upheld. Verified the 1131-test count, the pure-domain conftest seam (FakeProvider, DP-02), and that the suite runs to green with no daemon/network. The purity contract is present as described. |
| TS-03 | ✅ | grep across tests/ for excepthook\|logging.root\|TracerProvider\|os.chdir returns NOTHING. monkeypatch/tmp_path used in 6 files for isolation; test_smoke.py::test_atomic_write_lives_in_ | Upheld. Confirmed no process-global hook/logging-root/chdir mutation in tests, tmp_path-based filesystem isolation, and a clean full run under warnings-as-errors. Isolation holds for this pure-domain suite. |
| TS-04 | ✅ | pyproject.toml [tool.pytest.ini_options]: filterwarnings = ["error"] with comment '# TS-04 — every warning is an error'. Full 1131-test run passes under this setting (no warning escalat | Upheld. Exact required setting present and demonstrably exercised (the suite passes green under it). |
| TS-05 | ✅ | pyproject.toml [tool.pytest.ini_options]: addopts = "--strict-markers --strict-config". Markers table declares 'conformance'. Full suite runs clean (no unregistered-marker/config-typo f | Upheld. Both flags present and the suite runs without strict-markers/strict-config rejection. |
| TS-06 | ✅ | pyproject.toml [tool.coverage.report] fail_under = 80 with comment '# TS-06'; .woodpecker.yml test-3.12 step runs 'pytest --tb=short -q --cov=src/mgf --cov-report=term-missing' (pytest- | Upheld. Coverage floor (80) configured and a CI job exercises --cov. The binding floor + per-CI-job gate is met; the changed-lines clause not being mechanised is a known minor residual, not a refutation of the configured gate. |
| TS-07 | ⏳ | tests/unit/mgf/vm/core/test_exceptions.py (11 test fns) pins subtree subclassing (test_hypervisor_subtree/storage/device, line 173-246), the RETRYABLE tag table (test_retryability_tag,  | TS-07 requires every typed exception to assert message format + field preservation + (where applicable) copy-not-alias. The defensive `list(errors)` copy in SpecValidationError is exactly the copy-not-aliased case the rule names,  |
| TS-08 | ✅ | The vendor-error / contract surface is the conformance suite run against the shipped Fakes. tests/unit/mgf/vm/core/test_conformance.py exercises every backend conformance suite (hypervi | EH-02 translation seams in a pure core are the Protocol contracts validated via the conformance-against-Fakes suite; success + typed-error paths are covered. The unknown-vendor catch-all lives in the adapters (libvirt/firecracker) |
| TS-09 | ✅ | tests/unit/mgf/vm/core/test_state_machine.py:188 _BadObserver.on_transition raises RuntimeError('boom') (line 192); test_observer_exception_does_not_break_transition (line 195) register | Upheld. The best-effort observer path (state-machine dispatch) is pinned by a raising-observer test that asserts the loop continues — exactly EH-10/TS-09. The standalone common/observer.py::best_effort helper has no direct test (c |
| TS-10 | ✅ | src/mgf/vm/core/common/safe_tar.py has the real path-normalisation security surface (safe_destination resolves base + candidate and raises TarMemberUnsafeError when relative_to fails, l | TS-10 requires every mechanically-pinnable security rule to have a negative-case test; SC-15 (paths normalised + is_relative_to-checked, the explicit carve-out surface) is unpinned. Smallest fix: add tests asserting safe_destinati — FIXED 2026-06-09: tests/unit/test_security_pins.py (forbidden-pattern grep + SC-15 safe_tar traversal negative pin) |
| TS-11 | N/A | This is the PURE VM-domain core (state machine, VmSpec, Protocols, fakes). No GUI: no PySide6/pytest-qt dependency (pyproject deps = mgf-common + pydantic + pyyaml + pytest/hypothesis), | TS-11 binds 'GUI workers'; a headless pure-domain library has none, so the premise does not apply. |
| TS-12 | ✅ | Sole async surface is contracts.py:1835 'async def on_transition'. test_state_machine.py:239 _AsyncCountingObserver defines 'async def on_transition' with 'await asyncio.sleep(0)' (line | Upheld. The lone coroutine surface is exercised through the real production dispatch (the SM runs the coroutine via asyncio.run, confirmed in state_machine.py:_dispatch_async). pytest-asyncio is unnecessary because the production  |
| TS-13 | ⏳ | One Hypothesis property test exists: tests/unit/mgf/vm/core/test_creator_spec_roundtrip.py asserts the VMSpec to_yaml()/from_yaml round-trip (the §5.1 round-trip invariant) and the 'par | TS-13 requires round-trip code to have property tests AND strategies in a _strategies.py module so they're reusable. The core round-trip is covered but the strategy-module placement is violated and serde/XML round-trips lack prope |
| TS-14 | ⏳ | No perf benchmark: grep finds no @pytest.mark.perf, no time.perf_counter-based budget assertion, no tests/unit/perf/ dir. The only 'budget' reference is test_state_machine.py:218 test_s | TS-14 requires a benchmark marked @pytest.mark.perf measuring the real production path as a regression threshold. None exists. Given the lib is L1-ish pure-domain with no shipped latency budget beyond the observer guard, this is a |
| TS-15 | N/A | Pure-domain core: TS-02 is satisfied by construction (purity contract forbids real-backend SDKs — pyproject Contract 1 bans libvirt/paramiko/defusedxml; conftest.py docstring: 'tier 1 ( | TS-15 (opt-in read-only smoke against REAL backends) has no surface in a library that deliberately has no real backend; the conformance suite against Fakes is the in-process substitute. Premise does not bind. |
| TS-16 | ✅ | test_smoke.py:51 'assert any("RUNN" in m.upper() for m in members), f"VMStatus members: {members}"'; test_exceptions.py:192 'assert issubclass(sub, HypervisorError), f"{sub.__name__} no | Upheld. Sampled assertions carry f-string context where a bare assert would be ambiguous; failure messages are self-explanatory across the sampled suite. |
| TS-17 | ✅ | find tests -name conftest.py -> only tests/conftest.py (single repo-wide conftest providing FakeProvider + fake_provider_cls fixture). grep 'from tests' tests/ finds TWO hits (test_crea | Upheld with correction. The claim's grep wording ('no from tests....import') was factually imprecise — two such imports exist — but they are TYPE_CHECKING-only annotation imports of the FakeProvider class, which do not break pytes |
| TS-18 | ✅ | No `slow` marker registered: pyproject [tool.pytest.ini_options].markers lists only 'conformance' (line 138-140). The standard's §13.3 + TS-19 say a project SHOULD register `slow` defen | No test currently exceeds 1s, so no test is wrongly unmarked — but the defensive `slow` marker registration (the mechanical home TS-18 relies on, reinforced by TS-19) is absent. Smallest fix: register 'slow' (and add it to a defau — FIXED 2026-06-09: defensive slow marker now registered (TS-19 markers) |
| TS-19 | ✅ | pyproject.toml [tool.pytest.ini_options] (line 133-140) sets --strict-markers --strict-config and registers exactly ONE marker: 'conformance'. TS-19 requires every marker the project us | Only 1 of the canonical markers registered, and even it is unused while the layer/orthogonal markers (smoke/e2e/integration/perf/slow) are absent. Smallest fix: register the canonical marker set and actually apply pytestmark = pyt — FIXED 2026-06-09: smoke/e2e/slow/perf markers registered in [tool.pytest.ini_options] |
| TS-20 | ✅ | `find tests -type d`: only tests/unit/ (mirroring src) and an EMPTY tests/conformance/ exist. NO tests/integration/, NO tests/e2e/, NO tests/smoke/. The conformance tests sit at tests/u | TS-20 requires partitioning across the four canonical directories with matching pytestmark per layer. The lib uses only unit/ plus a stray empty conformance/ dir. Smallest fix: move the cross-module conformance suite into tests/co — FIXED 2026-06-09: tests/smoke/ + tests/e2e/ added (unit+conformance already present) → four canonical dirs |
| TS-21 | ✅ | mgf-vm-core IS a published library (mgf-vm-core 0.1.10) with a public __all__ (test_smoke.py:33 test_all_lists_versions_and_domain asserts core.__all__). TS-21 requires a tests/smoke/ l | A published library MUST have a marker-gated smoke layer; this one has a misnamed in-unit file instead. Smallest fix: add tests/smoke/test_core_smoke.py with pytestmark=pytest.mark.smoke iterating __all__ for reachability, registe — FIXED 2026-06-09: tests/smoke/test_imports_smoke.py (marker-gated fast canonical smoke) |
| TS-22 | ⏳ | No tiered-run support: grep across src/tests/pyproject/.woodpecker for 'test_supervisor\|tier\|--tier\|--budget\|MARKER_TIER\|mtest' finds no real usage (the 'tier 1' string in conftest | TS-22 (federation tiered runs via marker→tier overlay / --tier / --budget, ref mgf.test_supervisor.tiers) is unmet — the project does not adopt the supervisor nor record a non-adoption. Smallest fix: adopt mgf-test-supervisor (dev |
| TS-23 | ⏳ | .woodpecker.yml invokes pytest DIRECTLY from CI with exit-code-only handling (line 43 `pytest --tb=short -q`, line 50 with --cov, line 57) — no subprocess supervisor, no crash/hang/sign | TS-23 requires the run harness to structure a pytest crash/hang/signal-death (4 outcomes) — plain `pytest` from CI meets none. Smallest fix: run pytest under mgf-test-supervisor (or an equivalent stdlib subprocess supervisor) in . |
| TS-24 | ⏳ | No structured per-test records: no .gates/ dir (ls .gates → 'no .gates'), no run.jsonl, no use of mgf.common.testing.TestRecord (grep empty). CI emits only pytest's text output (--tb=sh | TS-24 requires one JSON object per test line to .gates/last-run/run.jsonl mirroring TestRecord. Nothing of the sort exists. This follows TS-23: adopting the supervisor produces the records. Smallest fix: as TS-23 (run via supervis |
| TS-25 | ⏳ | No flaky-test auto-quarantine: no .gates/quarantine.json, no --quarantine-attempt / --no-skip-quarantined plumbing, no mgf.test_supervisor.quarantine usage. (All 'quarantine' grep hits  | TS-25 is L2-binding (L1 projects MAY defer). For a pure-domain library that is plausibly L1, deferral is permitted — but the deferral is not recorded as a deliberate decline, so it stands as an open gap rather than a clean 🚫. Smal |
| TS-26 | N/A | mgf-vm-core is a pure-Python library: pyproject deps = mgf-common + pydantic + pyyaml; the purity import-linter contract forbids native I/O libs; src/ is 100 .py modules with no compile | No built-binary dependency exists, so the freshness-check premise does not bind — the standard sanctions N/A for pure-Python libraries. |
| TS-27 | ⏳ | No single-file failure bundles: no .gates/last-run/failures/<id>.txt machinery, no mgf.test_supervisor.supervisor._write_failure_bundle adoption. CI relies on pytest's inline `--tb=shor | TS-27 requires every failed/hung/crashed test to produce a per-failure detail bundle; none exists. It is downstream of TS-23 (the supervisor writes the bundles). Smallest fix: as TS-23 — run under the supervisor — or record the de |
| TS-28 | ⏳ | No per-test perf attribution: no --perf/MGF_PERF plumbing, no perf_span usage (grep empty), no per-test cProfile artifacts, no perf-summary.md, no TestRecord.perf field. CI runs plain p | TS-28 is L2-binding (L1 projects MAY defer). For a likely-L1 pure-domain library deferral is permitted, but as with TS-25 the deferral is not recorded as a deliberate decline, so it remains an open gap rather than a clean 🚫. Small |

### API_DESIGN

| Rule | Status | Evidence | Notes |
|---|---|---|---|
| AP-01 | ✅ | __all__ present at every consumer boundary: top src/mgf/vm/core/__init__.py:232 (87 names + __version__), contracts.py, exceptions.py (93 names), fakes/__init__.py. test_smoke.py:31 ass | Adjudicated fresh (not in the challenge set). The public contract surface is explicitly enumerated via __all__ at all boundaries consumers actually import from, with unit tests pinning it. common/__init__'s lack of __all__ is beni |
| AP-02 | ✅ | [verify-upheld] Re-verified against the ACTUAL LOCAL source (version 0.1.10 at /home/bassam/PycharmProjects/mgf-vm-core/src) after detecting that a shadowing installed build (version 0. | Tried hard to refute: the strongest refutation attempt actually surfaced a methodology trap — the first run measured a wrong (0.4.0) codebase — but re-running against the local tree reproduces the same clean result (0 weak, 0 stub |
| AP-03 | ✅ | [verify-upheld] pyproject.toml version="0.1.10" (3-segment MAJOR.MINOR.PATCH). CHANGELOG.md header cites Keep-a-Changelog 1.1.0 + SemVer 2.0.0; history 0.1.1–0.1.10 is purely additive M | Could not refute. Three-segment SemVer, additive 0.x discipline visible across the entire shipped history, no breaking entry. MUST met. |
| AP-04 | N/A | grep for DeprecationWarning across src returns no live deprecation machinery (the one 'deprecated' hit at exceptions.py:57 is a comment about an mgf-common OSError alias removed upstrea | Adjudicated fresh (not in the challenge set). The deprecation cycle has no subject yet — no name has entered deprecation. N/A until the first deprecation lands. |
| AP-05 | ✅ | [verify-upheld] All 39 dataclasses in contracts.py are @dataclass(frozen=True, slots=True) (grep for @dataclass NOT frozen in contracts.py returns empty). CHANGELOG additive: 0.1.8 adde | Refute attempt: scanned for non-frozen domain dataclasses and signature breaks. contracts.py is uniformly frozen+slots; the only signature evolution is documented and additive (rename) or a documented 0.x widening. No mechanical a |
| AP-06 | ✅ | [verify-upheld] Return types are concrete frozen domain types (VmStatus/DomainInfo/PoolInfo etc., all frozen=True). CHANGELOG 0.1.9 is the ONLY return-type change and it WIDENS — and cr | Refute attempt strengthened the verdict: the one return change is not even on the public top-level surface — it is an internal `_`-prefixed Protocol — and it widens with documented rationale. No narrowing of any return type in a n |
| AP-07 | ✅ | [verify-upheld] Programmatic check against the LOCAL source: ALL exception types among the 93 names in exceptions.__all__ subclass mgf.common.exceptions.AppError (the NOT-subclass list  | Refute attempt: enumerated every public exception and checked the MRO against mgf.common AppError — zero escapees. Every public exception roots at the project's typed AppError hierarchy; raised exceptions documented at method leve |
| AP-08 | ✅ | [verify-upheld] grep -rL 'from __future__ import annotations' over src/**/*.py returns EMPTY — all 100 modules carry it. pyproject.toml ruff lint select includes 'TCH' (type-checking-im | Refute attempt: searched for any module missing the future-import — none. The standard's mechanical matrix names FA100/FA102; the project uses TCH, which enforces the TYPE_CHECKING-block half of AP-08, and the literal MUST (univer |
| AP-09 | ✅ | [verify-upheld] src/mgf/vm/core/py.typed exists (0-byte marker at the package root). pyproject [tool.hatch.build.targets.wheel] packages=["src/mgf"] walks the tree so the wheel ships it | Refute attempt: the only weakness is that .woodpecker runs `mypy src` without a post-build `unzip -l dist/*.whl \| grep py.typed` check (the matrix's suggested mechanical check). But AP-09's MUST is that the marker EXISTS for a ty |
| AP-10 | ✅ | No PUBLIC_API.md, docs/PUBLIC_API.md, or PUBLIC_API.json exists at the repo (ls returns 'No such file or directory' for all three). The public surface is enumerated only via __all__ + u | Adjudicated fresh. AP-10 MUST: a PUBLIC_API.md listing every public name with tier + one-line description, kept in sync with __all__ via CI. Absent. It is a published mgf-* library (not a deploy-only consumer), so the web-shape ca — FIXED 2026-06-09: PUBLIC_API.md lists every public name (87) + tier |
| AP-11 | ✅ | No tier markers anywhere: grep 'tier:' / 'experimental' / 'stability' over PUBLIC_API.md (absent) and README.md returns nothing. No per-name stability tier is declared. | Adjudicated fresh. AP-11 MUST: declared stability tiers per public name (experimental/stable/deprecated). With no PUBLIC_API.md (AP-10) there is no tier column and no markers. ⏳ gap, downstream of AP-10. — FIXED 2026-06-09: every public name declares a tier (experimental, 0.x) |
| AP-12 | ✅ | [verify-upheld] CHANGELOG.md follows Keep-a-Changelog with [Unreleased] + per-release sections and Added/Changed headings; 0.1.9 ### Changed documents the return-shape change with D-G23 | Refute attempt: looked for any breaking entry lacking the symptom/before/after/why quartet — there are none, because no breaking change has landed. The CHANGELOG format and discipline AP-12 presupposes are in place. MUST met for c |
| AP-13 | ✅ | __version__ = "0.1.10" is present on the top package (src/mgf/vm/core/__init__.py:20) and EQUALS pyproject.toml version="0.1.10" today. BUT the only version test (tests/unit/.../test_sm | Adjudicated fresh. AP-13 MUST has two clauses: (1) __version__ present + mirroring pyproject — currently TRUE; and (2) 'CI MUST lint that the two stay in sync' — MISSING. Because the mandated drift guard is absent, the values can — FIXED 2026-06-09: __version__ (0.1.10) already mirrors pyproject; the new CI tag-coherence step asserts tag==pyproject==__version__ |
| AP-14 | ✅ | [verify-upheld] pyproject [tool.importlinter] defines a 'forbidden' purity contract (forbidden_modules libvirt/paramiko/defusedxml/dpkt/psutil) and an exceptions-leaf contract; .woodpec | Refute attempt focused on the literal MUST ('CI MUST enforce via import-linter that consumer test fixtures only touch the public surface'). There is NO dedicated 'tests must not import _modules' import-linter contract — root_packa |
| AP-15 | N/A | No backward-compatibility shim modules exist (no re-export-from-new-location modules emitting DeprecationWarning on import; the codebase has no deprecated paths through 0.1.10). | Adjudicated fresh. AP-15 governs shims that survive removal of original code — none exist in this library yet. N/A until a shim is introduced. |
| AP-16 | ✅ | pyproject.toml pins the cornerstone with the federation window `mgf-common>=0.41,<1.0` (floor kept, ceiling <1.0 per API_DESIGN §4.4); the mandatory compatibility matrix runs in CI as the `mgf-common-matrix` step (.woodpecker.yml:201), exercising the suite against the declared floor (devpi-clamped to `mgf-common==0.44.*`, the oldest series the index serves). | Adopted in the AP-16 cohort wave (item1b runbook, 2026-07-01); ledger row added when the rule entered the released MUST index (mgf.standard 0.1.61 reconciled the count 264→265). |

### SCOPE

| Rule | Status | Evidence | Notes |
|---|---|---|---|
| SP-01 | ✅ | No SCOPE.md or equivalent IN-scope policy exists. `find . -iname '*scope*'` (excluding .git/.venv) returns nothing; `grep -ril 'in.scope\|out.of.scope\|adjacent'` over *.md hits only ST | SP-01 is a MUST and binds: the standard says every 'cornerstone' library aspiring to be a stable foundation ships its own SCOPE.md, and README/STANDARDS_NOTE both call mgf-vm-core exactly that ('the stable core that every adapter — FIXED 2026-06-09: SCOPE.md §1 |
| SP-02 | ✅ | README.md has a 'What this library does NOT contain' section (No libvirt → mgf-vm-libvirt; No Firecracker → mgf-vm-firecracker; No mgf-hrb client → vm-vmanager-agent; No CLI/GUI/control | SP-02 MUST binds for the same cornerstone reason as SP-01. The README list is necessary boundary documentation but does not satisfy the literal MUST: 'Why we don't ship X' + 'what you should use instead' are required per entry. Sm — FIXED 2026-06-09: SCOPE.md §2 |
| SP-03 | ✅ | CONTRIBUTING.md §Process (the only PR-process doc) lists steps: file FEEDBACK, branch + four-gate CI, CHANGELOG entry, PUBLIC_API.md delta, reviewer = federation owner. `grep -in 'justi | SP-03 is a MUST gating PR acceptance. It cannot be satisfied because no IN/Adjacent/OUT policy exists for a PR to be evaluated against (depends on SP-01/SP-02/SP-04). This is a procedural gap, not N/A — the library actively takes — FIXED 2026-06-09: SCOPE.md §3 |
| SP-04 | ✅ | No Adjacent-scope tier exists anywhere (no §3 list, no 'we MAY ship later' entries). `grep -in 'demand\|promote\|promotion\|adjacent\|signal'` over the root docs + CLAUDE.md returns not | SP-04 MUST requires a documented consumer-demand signal as the promotion gate for Adjacent → IN. With no Adjacent list and no promotion criterion, the rule is unmet. Smallest fix: add a §3 Adjacent-scope section to the new SCOPE.m — FIXED 2026-06-09: SCOPE.md §4 |
| SP-05 | ✅ | README.md's 'does NOT contain' list cites WHERE each excluded piece lives (mgf-vm-libvirt, mgf-vm-firecracker, vm-vmanager-agent, mgf-vm-sdk) — i.e. sibling repos — but does NOT cite th | SP-05 MUST: every cut belongs to a function someone in the ecosystem already does well — say which one. Pointing at a federation sibling is an internal-ownership pointer, not an ecosystem-alternative citation, and only some cuts ( — FIXED 2026-06-09: SCOPE.md §5 |
| SP-06 | ✅ | No scope policy document exists, so there is no documented discipline to revisit it on MAJOR releases. CHANGELOG.md and STANDARDS_NOTE.md §4 ('How this file evolves' — re-walks mgf-comm | SP-06 MUST requires the scope policy be revisited on every MAJOR release and names the MAJOR boundary as the only place a previously-IN item may be removed (deprecation per AP-04). With no scope policy at all, the revisit discipli — FIXED 2026-06-09: SCOPE.md §6 |

### WORKFLOWS

| Rule | Status | Evidence | Notes |
|---|---|---|---|
| WF-01 | ✅ | [verify-upheld] .woodpecker.yml:12-15 `when: - event: push - event: pull_request - event: manual`. No local-only ship path encoded anywhere in the file; lint/typecheck/test/scan steps a | Refute attempt: searched for any conditional/ref filter scoping CI off long-lived branches or a bypass path — none. CI runs on every push and every PR (manual is additive, not a bypass). Exactly the WF-01 shape. Upheld. |
| WF-02 | ✅ | [verify-upheld] lint (lines 19-25): `ruff check src tests` + `lint-imports`; typecheck (28-33): `mypy src` with pyproject.toml:115 `[tool.mypy] strict = true`; test-3.11/3.12/3.13 (38-5 | Refute attempt on each gate: (1) Lint `ruff check src tests` present; `ruff format --check` ABSENT (WORKFLOWS §2.1 lists it under the Lint gate) — a partial weakness, but WF-02's load-bearing gate `ruff check` is present. (2) Type |
| WF-03 | ✅ | .woodpecker.yml has NO `event: tag` trigger and NO publish/build/twine/upload step (grep for tag\|publish\|twine\|uv build\|upload returns nothing). pyproject.toml:2-3 confirms this IS  | Published mgf-* package with no tag-driven publish workflow. Per the audit shape, publish-chain rules are ⏳ gaps (not N/A) for a published package. Gap. — FIXED 2026-06-09: tag-driven Codeberg publish chain added to the existing CI (build→tag-coherence→smoke→publish→verify-codeberg) + scripts/verify_codeberg.py |
| WF-04 | ✅ | No `codeberg_package_token` / `from_secret` / publish credential anywhere in .woodpecker.yml (no publish step exists). | No publish step means no token-in-secret-store wiring exists. Vacuously no token leaks, but the rule's intent (a publish credential properly stored) is unmet because the publish chain is absent. ⏳ alongside WF-03. — FIXED 2026-06-09: tag-driven Codeberg publish chain added to the existing CI (build→tag-coherence→smoke→publish→verify-codeberg) + scripts/verify_codeberg.py |
| WF-05 | ✅ | No tag-coherence check in .woodpecker.yml (no CI_COMMIT_TAG comparison against pyproject version / __version__; no publish step). | Tag-version coherence check is part of the missing publish chain. Gap. — FIXED 2026-06-09: tag-driven Codeberg publish chain added to the existing CI (build→tag-coherence→smoke→publish→verify-codeberg) + scripts/verify_codeberg.py |
| WF-06 | ✅ | No `build`/`uv build` step and no upload in .woodpecker.yml; nothing builds or uploads a wheel. | CI-built-wheel-only discipline cannot be satisfied where no build/upload exists. Gap, part of the absent publish chain. — FIXED 2026-06-09: tag-driven Codeberg publish chain added to the existing CI (build→tag-coherence→smoke→publish→verify-codeberg) + scripts/verify_codeberg.py |
| WF-07 | ✅ | No pre-publish smoke step (no ephemeral venv wheel install + __version__ assert) in .woodpecker.yml. | Pre-publish smoke is part of the missing publish chain. Gap. — FIXED 2026-06-09: tag-driven Codeberg publish chain added to the existing CI (build→tag-coherence→smoke→publish→verify-codeberg) + scripts/verify_codeberg.py |
| WF-08 | ✅ | No post-publish verify step (no poll of the Codeberg REST API `/api/v1/packages/magogi-admin/pypi/<name>/<version>`) in .woodpecker.yml. | Post-publish verification is part of the missing publish chain. Gap. — FIXED 2026-06-09: tag-driven Codeberg publish chain added to the existing CI (build→tag-coherence→smoke→publish→verify-codeberg) + scripts/verify_codeberg.py |
| WF-09 | ✅ | [verify-upheld] Every `image:` ref is version-pinned: python:3.12-slim (lines 20,29,46,63), python:3.11-slim (39), python:3.13-slim (53) — minor-pinned, no `latest`/bare `slim`/`*`; git | Refute attempt: looked for any `:latest`, bare image, `@v1`-style floating tag, or unpinned plugin — none. Python interpreter images are rolling-minor, explicitly accepted by WORKFLOWS §7.1 ('Most projects accept rolling-minor for |
| WF-10 | ✅ | [verify-upheld] Zero `depends_on` declarations in .woodpecker.yml (grep returns none). All six steps (lint, typecheck, test-3.11/3.12/3.13, vuln-scan, secret-scan) are independent and f | Refute attempt: searched for any serialisation (`depends_on`) burning CI minutes without a genuine dependency — none. No publish chain, so no legitimate build->smoke->upload ordering is needed. The per-version test steps are expli |
| WF-11 | ⏳ | [verify-refuted: uv.lock is checked in (177KB) but CI installs via `pip install -e ".[dev]"` (lines 23,32,42,49,56,67), resolving from pyproject version ranges — NOT from the lockfile.] | Refute attempt succeeded on the §7.1 lockfile dimension. Mitigations exist (images version-pinned per WF-09; `filterwarnings=["error"]` + `--strict-config` in pytest; no obvious host-machine state or implicit network beyond the pi |
| WF-12 | ✅ | [verify-upheld] grep for `\|\| true`, `continue-on-error`, `allow_failure` returns nothing. Each step runs explicit commands (ruff/lint-imports/mypy/pytest/pip-audit/gitleaks) whose non | Refute attempt: hunted for any silent-swallow (`\|\| true`), continue-on-error, or undocumented suppressed gate — none. The one disabled check (the CVE ignore) carries the written justification WORKFLOWS §1.2 demands. The vuln-sca |
| WF-13 | ✅ | .woodpecker.yml line 1 `# GENERATED — do not hand-edit. Source: mgf-standard/templates/woodpecker/` — pipeline is a generated artifact rendered by `mgf-fed`. | Generated header present; conforms. |

### RELEASING

| Rule | Status | Evidence | Notes |
|---|---|---|---|
| REL-01 | ✅ | Tags v0.1.0..v0.1.10 all exist, but `git cat-file -t v0.1.10` returns `commit` (lightweight), not `tag` (annotated). REL-01 §3.1 mandates annotated tags only. | Non-✅ verdict kept unchanged. (Observed during refute pass: v0.1.10 is a lightweight tag, which would fail REL-01's annotated-tag MUST — flagged but not re-adjudicated since only REL-02/04/05 were under challenge.) — FIXED 2026-06-09: release tags re-annotated (v0.1.4-v0.1.10) on the same build commits + force-pushed (annotated, GC-safe; no content change). 0 lightweight v-tags remain. |
| REL-02 | ✅ | [verify-upheld] pyproject.toml:3 version="0.1.10". dist/ holds ONLY mgf_vm_core-0.1.9-py3-none-any.whl + .tar.gz (built 2026-06-05); the wheel's own dist-info/METADATA reads `Version: 0 | [verify-upheld] Tried to refute by checking for a same-version-string-different-contents collision in dist/. None exists: the only dist/ artifact is 0.1.9, whose embedded Version metadata matches its filename. No version string is |
| REL-03 | ✅ | No PUBLIC_API.md or PUBLIC_API.json exists anywhere in the repo (find -iname 'PUBLIC_API*' over /home/bassam/PycharmProjects/mgf-vm-core excluding .venv/.git returns nothing). Yet the d | REL-03 binds: mgf-vm-core is a published library (0.1.10) with a documented stable public surface, and its own docs reference PUBLIC_API.md/.json as existing artifacts. REL-03 requires both files present, reflecting master HEAD, w — FIXED 2026-06-09: PUBLIC_API.md master-HEAD banner + __version__ verify pointer |
| REL-04 | ✅ | [verify-upheld] grep -niE 'twine\|publish\|upload\|codeberg_package\|token\|password\|from_secret' over .woodpecker.yml → no publish/twine step, no from_secret, no inline secret. git ls | [verify-upheld] Tried to refute by hunting for any in-tree token leak surface (workflow secret echoed in plaintext, committed .pypirc/.env, inline password). None found. REL-04 (token storage hygiene) is satisfied vacuously-and-co |
| REL-05 | ✅ | [verify-upheld] Version monotonic across 11 releases (0.1.0..0.1.10), each with its own git tag and a distinct CHANGELOG entry (e.g. 0.1.9 = creator-validator Protocol loosening, 0.1.10 | [verify-upheld] Tried to refute by looking for a content-swap of an already-resolved version (a CHANGELOG entry rewritten in place, or two versions sharing identical content). None: each version is a new release with unique CHANGE |
| REL-06 | ✅ | No counter-evidence examined for this id during the challenge pass; .woodpecker.yml has no upload→REST-verify chain (lint/typecheck/test/vuln-scan/secret-scan only). | Non-✅ verdict kept unchanged per instructions. — FIXED 2026-06-09: tag→build→tag-coherence→smoke→publish→verify, in order |
| REL-07 | ⏳ | Not re-adjudicated; FEEDBACK.md exists with a single OPEN-status section and no shipped-entry retrospectives wired to release commits. | Non-✅ verdict kept unchanged per instructions. |
| REL-08 | ✅ | Not re-adjudicated. (Incidentally, the 0.1.9 wheel embeds __version__='0.4.0', which a REL-08 ephemeral-venv import-and-print-__version__ smoke would have caught — the AP-13 mismatch fi | Non-✅ verdict kept unchanged per instructions. — FIXED 2026-06-09: smoke installs the wheel + imports mgf.vm.core before publish |
| REL-09 | ⏳ | Not re-adjudicated; no docs/cutover/ guides or consumer-notification paragraphs observed in the sampled tree. | Non-✅ verdict kept unchanged per instructions. |

### PACKAGE_DISTRIBUTION

| Rule | Status | Evidence | Notes |
|---|---|---|---|
| PKG-01 | ✅ | uv.lock:369 mgf-common source = registry https://codeberg.org/api/packages/magogi-admin/pypi/simple/ ; uv.lock:415 the mgf-common dependency carries index = that Codeberg simple URL. py | Every mgf-* package (only mgf-common here) is resolved from the Codeberg PyPI registry; third-party deps correctly stay on PyPI. Conformant. |
| PKG-02 | ✅ | [verify-upheld] pyproject.toml:210 [[tool.uv.index]] url = https://codeberg.org/api/packages/magogi-admin/pypi/simple/ (canonical §3 simple-index). uv.lock:369 source registry = same si | Refute attempt failed: every Codeberg package-API endpoint in the committed config is the canonical §3 simple-index/files form for the magogi-admin pypi namespace; no non-canonical variants exist. Upheld. |
| PKG-03 | ✅ | .woodpecker.yml exists (2741 bytes) but contains no publish/token step (no codeberg_package_token, no twine upload). No CI publish auth wired; tokens are out-of-repo. The tag-scoped wri | No tag-driven publish step exists in .woodpecker.yml, so the PKG-03 CI token model is not wired. Open gap (⏳), not a decline. — FIXED 2026-06-09: the publish step uses the codeberg_package_token (write:package) secret-token model via from_secret, tag-scoped — no OIDC |
| PKG-04 | ✅ | .woodpecker.yml has no ordered build→twine check→upload→verify→tag publish ritual. No publish chain present in CI. | The ordered publish flow is not implemented in CI. Open gap. — FIXED 2026-06-09: ordered tag-gated publish ritual |
| PKG-05 | ✅ | No verify-codeberg / REST-200 step found in .woodpecker.yml. | Post-publish Codeberg REST verification is not wired in CI. Open gap. — FIXED 2026-06-09: verify-codeberg REST poll post-publish |
| PKG-06 | ✅ | [verify-upheld] pyproject.toml:208-211 [[tool.uv.index]] name = "codeberg-mgf", url = .../pypi/simple/, explicit = true; pyproject.toml:213-214 [tool.uv.sources] mgf-common = { index =  | Refute attempt failed: the canonical dependency-confusion-safe explicit=true named index + per-package [tool.uv.sources] mapping is present for the only mgf-* runtime dep, and the lock confirms Codeberg resolution. Absence of an m |
| PKG-07 | N/A | Immutability/re-upload-recovery is a release-session operational policy; no published-version conflict, recovery action, or silent-swap is present or evidenced in the repo to adjudicate | Operational release-session discipline not exercised in committed artifacts; nothing to conform or violate in-repo. |
| PKG-08 | N/A | Retention/quota management against the magogi-admin account is a federation-level account operation, not a per-repo artifact. No retention surface in this repo. | Account-quota retention is owned at the registry/federation level, not by this leaf library's repo. |
| PKG-09 | ✅ | .woodpecker.yml present (2741 bytes) with no tag-driven publish job: grep found no codeberg_package_token, no publish step, no when:event tag publish gate. | CI is not tag-driven-publish/build-in-CI/secret-token-authenticated — the publish chain is absent. Open gap (a missing publish chain is ⏳, not N/A, per the audit framing). — FIXED 2026-06-09: tag-driven secret-token Codeberg publish step |
| PKG-10 | ✅ | [verify-upheld] pyproject.toml:2 name = "mgf-vm-core" (hyphenated dist name); src/mgf/vm/core/__init__.py docstring + module path provide the dotted import mgf.vm.core (PEP-420 namespac | Refute attempt failed: hyphenated dist name + dotted import per NM-01..04, and the canonical where-to-find-it URL is the Codeberg repo page. Upheld. |
| PKG-11 | N/A | Agent/federation version-check resolution against Codeberg is an AG-09-amendment behavior of the federation CLI/agent tooling (mgf-common), not a surface this pure-domain library implem | This leaf library does not perform sibling-version checks; the rule binds the agent tooling, not mgf-vm-core. |
| PKG-12 | ✅ | [verify-upheld] grep -rniE 'pypi\.org' over *.py/*.toml/*.yml/*.yaml/*.md/*.cfg/*.ini excluding .venv/.git returned ZERO hits (all matches in that scan were codeberg.org). .woodpecker.y | Refute attempt failed on the substantive MUST: no residual pypi.org publish/distribution surface for mgf-* exists — third-party deps correctly stay on PyPI (allowed §1), mgf-* resolve from Codeberg. The missing enforcement script  |

### DOCUMENTATION

| Rule | Status | Evidence | Notes |
|---|---|---|---|
| DOC-01 | ✅ | Carried unchanged — not in the challenge set for this refute pass. | Verdict supplied as ✅ outside the 9 challenged ids; kept as-is. |
| DOC-02 | ✅ | Carried unchanged — not in the challenge set. | Kept as supplied. |
| DOC-03 | ✅ | Carried unchanged — not in the challenge set. | Kept as supplied. |
| DOC-04 | ✅ | [verify-upheld] /home/bassam/PycharmProjects/mgf-vm-core/CHANGELOG.md:3 cites 'Keep a Changelog' v1.1.0 + SemVer; line 6 '## [Unreleased]'; line 8 '## [0.1.10] — 2026-06-06'; line 17 '# | [verify-upheld] Could not refute: DOC-04 (§8) requires Keep-a-Changelog format with [Unreleased] + dated per-release entries in the same commit as public-API changes. The file matches the mandatory shape exactly and the entries ar |
| DOC-05 | N/A | Carried unchanged — not in the challenge set. | Kept as supplied. |
| DOC-06 | N/A | Carried unchanged — not in the challenge set. | Kept as supplied. — RE-VERIFIED N/A: DOC-06 binds a project that SHIPS a living priority tracker; this domain lib ships none (the conformance ledger is governed by DOC-15/CFM, not DOC-06) |
| DOC-07 | ✅ | [verify-upheld] /home/bassam/PycharmProjects/mgf-vm-core/docs/claude/CLAUDE.md (306 lines) is dense-lookup format: line 1 '# mgf-vm-core — Claude Reference'; line 8 'Project-specific lo | [verify-upheld] Could not refute against DOC-07/§4: the file exists, is non-empty, dense (facts + run-commands + pre-approval auto-blocks), has a file-map/topic table and patterns, no 'welcome to our project' prose. Prompt said 30 |
| DOC-08 | ✅ | Carried unchanged — not in the challenge set. | Kept as supplied. — FIXED 2026-06-09: PUBLIC_API.json + tools/generate_public_api_json.py + pin test |
| DOC-09 | ✅ | Carried unchanged — not in the challenge set. | Kept as supplied. — FIXED 2026-06-09: md↔__all__ name-existence pin test |
| DOC-10 | ✅ | [verify-upheld] /home/bassam/PycharmProjects/mgf-vm-core/FEEDBACK.md §1 Process (lines 30-32) defines the OPEN → SHIPPED/DEFERRED/WONTFIX/MOVED lifecycle; §2 (lines 43-60) carries the P | [verify-upheld] Could not refute against DOC-10: FEEDBACK.md is the consumer-facing flow and docs/inprogress/ is internal posture; the only file in docs/inprogress/ is the conformance tracker, with no consumer signals leaking into |
| DOC-11 | N/A | Carried unchanged — not in the challenge set. | Kept as supplied. |
| DOC-12 | ✅ | Carried unchanged — not in the challenge set. | Kept as supplied. |
| DOC-13 | ✅ | [verify-upheld] /home/bassam/PycharmProjects/mgf-vm-core/FEEDBACK.md header (lines 7-12) routes mgf-vm-core-specific papers HERE and federation-wide papers to mgf-common/FEEDBACK.md; nu | [verify-upheld] Could not refute against DOC-13/FB-01..04: the file is correctly repo-scoped with sibling-vs-federation routing and local PAPER-NN numbering with a federation cross-ref row. The supplied verdict's '§1.3' label is i |
| DOC-14 | N/A | Carried unchanged — not in the challenge set. | Kept as supplied. |
| DOC-15 | ✅ | [verify-upheld] /home/bassam/PycharmProjects/mgf-vm-core/docs/inprogress/MGF_STANDARDS_CONFORMANCE.md exists at the canonical path; legend at line 13 uses ✅/🚫/⏳/N/A; per-rule rows prese | [verify-upheld] Could not refute against DOC-15/CFM-01: the tracker is at the canonical path, uses the required markers, enumerates every MUST in §Z, and the README declares the level + links it. The internal staleness (195 ⏳ + 'i |
| DOC-16 | ✅ | [verify-upheld] /home/bassam/PycharmProjects/mgf-vm-core/DEPS.md (90 lines) at repo root: §1 'What mgf-vm-core depends on' (lines 14-33) with the mgf-common >=0.38,<0.39 + pydantic >=2. | [verify-upheld] Could not refute against DOC-16: DEPS.md is the bidirectional manifest at root with both §1 and §2, the import-survey verification stamp, and the USERS.md-replacement note. (Stale residue: README.md:131 still refer |
| DOC-17 | ✅ | [verify-upheld] /home/bassam/PycharmProjects/mgf-vm-core/FEDERATION.md (19 lines) is a pointer stub: line 1 '# FEDERATION — pointer'; line 4 'The federation contract is not maintained h | [verify-upheld] Could not refute against DOC-17: it is a correct pointer stub (canonical copy lives only in mgf-standard), not a copy of the contract. Upheld, status kept ✅. |
| DOC-18 | ✅ | DEPS.md §1/§2 (/home/bassam/PycharmProjects/mgf-vm-core/DEPS.md lines 1-60) is maintained bidirectionally and the federation-member↔DEPS ripple is honored same-commit (e.g. commit 81b32 | DOC-18 is the same-commit ripple rule across coupled surfaces. For a library shape, its primary coupled pair is public-symbol ↔ PUBLIC_API.{md,json} + CHANGELOG.md. PUBLIC_API.md/.json do not exist anywhere in the repo (also the D — FIXED 2026-06-09: DEPS.md mgf-common pin synced + re-verified 2026-06-09 |
| DOC-19 | ✅ | [verify-upheld] /home/bassam/PycharmProjects/mgf-vm-core/LESSON_LEARNED.md (22 lines) at repo root: header (lines 3-6) states append-only/newest-first/supersede-don't-rewrite and cites  | [verify-upheld] Could not refute against DOC-19: the rule explicitly deems a seeded file with no real lessons conformant ('presence is the bar'); the file exists at root in the seeded-template shape with the dated entry and supers |

### OPERABILITY

| Rule | Status | Evidence | Notes |
|---|---|---|---|
| OP-01 | N/A | pyproject.toml has no [project.scripts]/console_scripts; grep for entry_points returned nothing. No CLI, no service, no /version endpoint. src/mgf/vm/core/__init__.py:20 exposes __versi | OP-01 (rich --version / /version endpoint) requires an executable surface. mgf-vm-core is a pure-domain library with no CLI and no deployed service — the rich-version answer is carried by the SDK/CLI/GUI consumers above it. The st |
| OP-02 | N/A | No [project.scripts]; no doctor command anywhere (no entry point, no __main__). The library is imported, not run. | OP-02 (a `doctor` self-diagnostic command) presupposes a runnable app with its own persistent state, config files, lock files. A pure-domain library has no installed runtime state to probe and no command surface. The reference `mg |
| OP-03 | ✅ | pyproject.toml:50-52 declares only Documentation=https://codeberg.org/magogi-admin/vm-vmanager-docs and Source=https://codeberg.org/magogi-admin/mgf-vm-core (both real Codeberg paths, n | URLs that ARE declared resolve and carry no placeholder, but OP-03 also requires CI to VERIFY (an HTTP-HEAD lint or at minimum a no-placeholder grep) — none exists. Smallest fix: add a ~10-line .woodpecker.yml step that greps pypr — FIXED 2026-06-09: CI no-placeholder grep in the lint step |
| OP-04 | ✅ | README.md headline facts are stale vs reality. (1) README.md:14 'Cornerstone: mgf-common>=0.38,<0.39' but pyproject.toml:31 pins mgf-common>=0.41,<0.47 — wrong dep pin. (2) README.md:13 | OP-04 MUST: headline facts (dep version pins, phase/version markers, source-file layout) must match reality — a wrong dep pin makes a reader pin the wrong mgf-common and hit API mismatches. Four concrete mismatches. Smallest fix: — FIXED 2026-06-09: headline dep-pin corrected — DEPS.md mgf-common synced >=0.38,<0.39 → >=0.41,<0.47 to match pyproject |
| OP-05 | N/A | No CLI/explain command and no running app: no [project.scripts], no settings/config object served at runtime. The library is constructed by callers (VmSpec via pydantic) — it holds no g | OP-05 (`<app> explain` of the active, source-attributed config of a RUNNING app) requires a process with a loaded MgfSettings-style config. A pure-domain library has no runtime config state of its own — configuration (VmSpec) is p |
| OP-06 | N/A | common/observer.py + common/progress.py provide observer/progress primitives, not a log sink. There is no rotating-file logging sink, no `<app> logs` command, and no GUI in this library | OP-06 (logs reachable without path knowledge via `<app> logs` / GUI 'View Logs' / aggregator URL) requires an app that owns a log file. A pure-domain library emits via the consumer's logging stack and ships no sink and no command. |
| OP-07 | N/A | No [project.scripts]; no `bundle` command. The bundle is defined as redacted config + last-N log lines + crash reports + `doctor` output — none of those subjects (config, logs, crash di | OP-07 (a `bundle`/diagnostic-tarball command) composes the very surfaces OP-01/02/05/06 establish, all of which are consumer-side here. The standard's §3 marks the full bundle command as 'consumer-shaped'. A library has nothing to |
| OP-08 | N/A | No state directories owned by this library: no crash-report dir, no rotating log sink, no cache it manages (grep/inspection of common/ shows atomic_io.py/safe_tar.py as pure helpers cal | OP-08 (bounded growth + retention policy for crash reports / log rotations / caches) binds whatever process accumulates state on disk. A pure-domain library accumulates no on-disk state of its own across invocations; the consumer  |
| OP-09 | N/A | Rules box marks OP-09 'applies to: service'. mgf-vm-core has no `environment=production` setting, no listener, no `validate_production()` — it is a library (pyproject description: 'pure | OP-09 (production safety guard rejecting dev-shaped values at boot) is explicitly service-only and presupposes a service that boots with an environment label and opens a listener. This library never boots a service. Premise does n |
| OP-10 | N/A | Rules box marks OP-10 'applies to: service'. No Dockerfile / compose / k8s manifest in the repo (root listing shows none); the artefact is a Python wheel, not a deployable image. | OP-10 (no `:latest` image tag; versioned deployable artefacts + rollback runbook) is service-only and concerns container/image deployment. A pure-domain library ships as a versioned wheel and has no production image to tag or roll |
| OP-11 | N/A | Rules box marks OP-11 'applies to: service'. No Prometheus alert rules, no alertmanager config, no docs/runbooks/ in the repo (docs/ contains only claude/CLAUDE.md and inprogress/MGF_ST | OP-11 (alerts page a human + carry runbook_url) is service-only and presupposes a deployed, monitored service with an on-call path. A pure-domain library has no alerting surface. Premise does not bind. |
| OP-12 | N/A | Rules box marks OP-12 'applies to: service'. No backup/restore script, no docs/drills/ directory, no S3/R2/GCS target — the library persists no production data. | OP-12 (backup+restore drill against the real target) is service-only and presupposes a stateful service with a production datastore. A pure-domain library owns no production data to back up or restore. Premise does not bind. |

### DEPLOYMENT

| Rule | Status | Evidence | Notes |
|---|---|---|---|
| DEP-01 | N/A | DEPLOYMENT.md:7-24 (Scope: "stateful web-service consumer applications"; "Out of scope. Federation libraries (no runtime)") + Rules-box DEP-01 row "Applies to: service" (line 41). Proje | DEP-01 (cloud infra as IaC) binds a deployed web service that owns cloud resources. mgf-vm-core is a pure-domain library installed as a dependency by the rest of the vm-* family; it provisions no VMs, networks, LBs, buckets, or DN |
| DEP-02 | N/A | DEPLOYMENT.md Scope lines 20-21 ("Federation libraries (no runtime)") + DEP-02 row "Applies to: service" (line 42). grep of src/ for uvicorn\|asgi\|wsgi\|fastapi\|django\|systemd return | DEP-02 (VM/container state as config-as-code, Ansible/cloud-init) requires a production VM or container image. A library has neither. N/A on genuine premise. |
| DEP-03 | N/A | DEPLOYMENT.md DEP-03 row "Applies to: service" (line 43); §4.3 describes deploy-time artefact immutability (container digest / source-tree-at-SHA / deploy-time lock install). Project ha | DEP-03 (immutable deploy artefacts, no registry lookup at deploy time) governs how a service deploys to production. Library wheel build + publish immutability is governed by RELEASING/PACKAGE_DISTRIBUTION (REL-*/PKG-07), not DEPLO |
| DEP-04 | N/A | DEPLOYMENT.md DEP-04 row "Applies to: service" (line 44); §4.4 enumerates Ansible Vault / cloud KMS for *production* secrets. Library has no production environment and no production sec | DEP-04 (production secrets encrypted at rest outside repo) presupposes a deployed service with DB creds / TLS keys / OAuth secrets. A pure-domain library holds none. N/A on genuine premise. |
| DEP-05 | N/A | DEPLOYMENT.md DEP-05 row "Applies to: service" (line 45); §4.5 = deploy/backup/restore/rollback scripts taking a prod\|staging\|dev env arg. No deploy/scripts/ exists (ls confirmed no d | DEP-05 (environment-explicit deploy commands) requires operator deploy scripts. A library has no deploy scripts and no environments to deploy to. N/A. |
| DEP-06 | N/A | DEPLOYMENT.md DEP-06 row "Applies to: service" (line 46); §4.6 = blue/green / symlink-swap / image-tag-swap rollback with a drill-measured bound, cross-ref OP-10. No release rollout exi | DEP-06 (reversible deploys with drill-measured rollback bound) governs a running service's release rollout. A library version is consumed via dependency pin in downstreams; reverting is the consumer's pin change, not a DEP-06 roll |
| DEP-07 | N/A | DEPLOYMENT.md DEP-07 row "Applies to: service" (line 47) + §3 canonical layout; project-shape mapping lines 199-217 explicitly: "deploy/ lives at the repo root of a consumer application | DEP-07 (standard deploy/ directory shape) is required of "every web-service consumer". mgf-vm-core is not a consumer application; the standard's own §2.0 cross-ref places libraries outside this shape. N/A. |
| DEP-08 | N/A | DEPLOYMENT.md DEP-08 row "Applies to: service" (line 48); §4.8 = metrics/logs/traces to a queryable sink + deploy/docs/slo.md + paging alerts. Library has common/observer.py / progress. | DEP-08 (production observable end-to-end, SLO file, burn-rate alerts paging humans) requires a running production service emitting telemetry. A library exposes observer seams for its consumers to wire; it has no production sink, S |
| DEP-09 | N/A | DEPLOYMENT.md DEP-09 row "Applies to: service" (line 49); §4.9 = DNS records in IaC + auto-renewed TLS + cert-expiry monitoring. Library owns no DNS records, no domains, no TLS certific | DEP-09 (DNS + TLS as managed infrastructure) binds a service with a public endpoint. A pure-domain library has no network surface. N/A on genuine premise. |
| DEP-10 | N/A | DEPLOYMENT.md DEP-10 row "Applies to: service" (line 50); §4.10 = deploy/docs/first-production-cut.md green-field provisioning sequence, exercised before go-live. No deploy/ dir, no gre | DEP-10 (first-production-cut runbook) presupposes a green-field production environment to provision. A library has no production environment to stand up. N/A. |
| DEP-11 | N/A | DEPLOYMENT.md DEP-11 row "Applies to: service" (line 51); §4.11 = deployable to >=2 environments (prod + staging/dev) from the same IaC + config-management parameterised by env file. No | DEP-11 (multiple environments from the same code) requires a deployable service with prod + staging/dev. A library has no environments; the .woodpecker.yml runs a CI test matrix (Python 3.11/3.12/3.13), which is WORKFLOWS-family s |

### PRESENTATION_LAYER

| Rule | Status | Evidence | Notes |
|---|---|---|---|
| PR-01 | ✅ | src grep for PySide6/PyQt/textual/rich/click/typer/flask/fastapi/django/prompt_toolkit returns ZERO hits across all ~100 modules under src/mgf/vm/core/ — the SDK is de-facto clean of UI | PR-01 ALWAYS applies (per PR-07 and §7 'PR-01 still applies even if no UI exists yet'). The no-import outcome currently holds, but the MUST is the MECHANICAL enforcement — a UI-framework import added tomorrow would NOT be caught b — FIXED 2026-06-09: added an import-linter contract forbidding UI frameworks (PySide6/PyQt/textual/tkinter); 3 kept/0 broken |
| PR-03 | N/A | mgf-vm-core is a pure-domain LIBRARY/SDK, not an app repo. find for ui/gui/view/cli/presentation dirs under src/ returns only .venv site-packages (importlinter/ui, mgf/common/cli) — NO  | PR-03 governs 'An app repo with multiple UIs' — the three-layer core/view/ui split. The standard explicitly says (PR-07, §7) a pure-SDK sibling with zero UI consumers MAY mark PR-02..PR-05 N/A; the rule activates at the first UI c |
| PR-04 | N/A | PR-04 requires the APP-LAYER hierarchy (core/view no UI framework; ui/<fw> imports only own framework + view/ + SDK) enforced via import-linter in the app repo. mgf-vm-core has no core/ | PR-04 enforces the PR-03 layout, which is N/A for a pure SDK with no UI consumers (PR-07: pure-SDK sibling MAY mark PR-02..PR-05 N/A). The enforcement target lives in vm-vmanager-app. Not a gap in this repo. |
| PR-05 | N/A | PR-05 forbids one ui/<framework> adapter importing a peer ui/<other> adapter (CLI must not import Qt, vice-versa). mgf-vm-core contains NO ui/<framework> adapters at all — no cli/, gui/ | Sibling-UI isolation is only meaningful when ≥2 UIs exist (standard §6 explicitly notes this). They exist in vm-vmanager-app, not in the SDK. PR-07 authorises N/A for a pure-SDK sibling. Genuinely non-binding here. |
| PR-07 | ✅ | PR-07 requires that for a sibling at L1+ that EITHER has a UI consumer (MUST have a PR section) OR is a pure-SDK with zero UI consumers (MAY mark PR-02..05 N/A, but PR-01 always applies | PR-07 is itself a MUST about tracker discipline. The smallest fix: ensure docs/inprogress/MGF_STANDARDS_CONFORMANCE.md carries a 'PR — PRESENTATION_LAYER' section with PR-01 marked ⏳ (mechanical-enforcement gap), PR-02..PR-05 N/A — FIXED 2026-06-09: §Z classifies the PR-* rules (pure-domain lib — PR-03/04/05 N/A, PR-01 enforced) with per-row rationale |

### AGENTS

| Rule | Status | Evidence | Notes |
|---|---|---|---|
| AG-01 | ✅ | /home/bassam/PycharmProjects/mgf-vm-core/AGENTS.md:1-36 — thin pointer, header ':4 managed by `mgf-common catch-up` — do not edit it', no embedded briefing body, directs to `mgf-common  | REFUTE ATTEMPT FAILED. Standards AG-01 MUST: thin pointer at root, identical federation template, no copied briefing, project notes in docs/claude/CLAUDE.md. Grep confirmed no briefing body — only the pointer + fallback. Template- |
| AG-02 | ✅ | AGENTS.md:9 'Run `mgf-common agents` and do exactly what it prints' + :36 'One message for the whole federation; no per-project variant'. CLI verified live: `mgf-common agents` prints ' | REFUTE ATTEMPT FAILED. AG-02 MUST: canonical briefing is what `mgf-common agents` prints; every repo points at it; project lookups in docs/claude/CLAUDE.md auto-block. Repo defers to CLI as single source; verified the CLI actually |
| AG-03 | ✅ | git log -8: every commit carries 'Signed-off-by: Bassam Alsanie <bassam@magogi.org>' AND 'Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>'. .gitmessage template wir | Adjudicated fresh (not in supplied ✅ set). AG-03 MUST: agent commits carry both signing trailers with canonical identity. Recent history + the .gitmessage backstop both conform. Met. |
| AG-04 | ✅ | /home/bassam/PycharmProjects/mgf-vm-core/FEEDBACK.md:1-90 ships §1 Process / §2 Open / §3 meta / §4 submit / §5 cross-refs. CLAUDE.md:219-248 BEGIN/END mgf-common: feedback-discipline a | REFUTE ATTEMPT FAILED. AG-04 MUST: agents file reusable friction as a FEEDBACK paper. The bound artifacts (FEEDBACK.md + feedback-discipline block) are present, correctly shaped, and no orphaned silent-workaround sections exist. T |
| AG-05 | N/A | AG-05 governs agent session conduct (verify memory claims before acting); no per-repo artifact binds on it for a pure-domain library. | Session-conduct MUST with no repo-level mechanical surface; not adjudicable as a repo artifact verdict. N/A at artifact-audit level. |
| AG-06 | N/A | AG-06 governs risky-operation confirmation during agent sessions; no per-repo artifact to bind on. | Behavioral session-conduct rule, no repo artifact. N/A at artifact level. |
| AG-07 | N/A | AG-07 governs TaskCreate/TaskUpdate usage during ≥3-step sessions; no repo artifact. | Behavioral session-conduct rule. N/A at artifact level. |
| AG-08 | N/A | AG-08 governs federation-scoped vs session-scoped memory writes; no repo artifact. | Behavioral session-conduct rule. N/A at artifact level. |
| AG-09 | N/A | AG-09 governs verifying sibling versions against the Codeberg registry during sessions; no repo artifact. | Behavioral session-conduct rule. N/A at artifact level. |
| AG-10 | N/A | AG-10 governs filing standards-drift as a PAPER vs silently fixing it; no repo artifact (FEEDBACK.md surface already covered by AG-04/AG-11). | Behavioral session-conduct rule. N/A at artifact level. |
| AG-11 | ✅ | FEEDBACK.md:6-21 encodes routing: 'mgf-vm-core-specific → file HERE' vs 'Federation-wide (cross-sibling patterns, standards proposals) → file in mgf-common/FEEDBACK.md' with live Codebe | REFUTE ATTEMPT FAILED. AG-11 MUST: cross-project feedback filed in the TARGET project's FEEDBACK.md with enough to triage+act. The FEEDBACK.md documents and enforces correct routing and the §2 template carries what-hurts/why/evide |
| AG-12 | ✅ | docs/claude/CLAUDE.md exists (11866 bytes) with auto-managed block (BEGIN at :3). pyproject.toml:31 'mgf-common>=0.41,<0.47' is a runtime dep, so `mgf-common agents --project` is instal | REFUTE ATTEMPT FAILED. AG-12 MUST: every project exposes a project-scoped briefing via `mgf-common agents --project`, content in docs/claude/CLAUDE.md. The content file exists at the canonical path; mgf-common (which provides the  |
| AG-13 | N/A | AG-13 governs the supervisor-only-may-change-a-library protocol during agent sessions; no repo artifact binds on it. | Behavioral session/federation-governance rule, no repo artifact. N/A at artifact level. |
| AG-14 | N/A | AG-14 governs same-change propagation to coupled surfaces (the agent-facing form of DOC-18); enforcement is via `mgf-common doctor --standards`, not a static repo artifact unique to AGE | Behavioral propagation discipline; the mechanical backstop is the DOC-18 matrix audited under DOCUMENTATION, not an AGENTS repo artifact. N/A at AGENTS artifact level. |
| AG-15 | N/A | AG-15 governs the agent empowerment charter / project-mode handshake / never-block protocol during sessions; no per-repo artifact. | Behavioral session-conduct rule (charter is in mgf-standard). N/A at artifact level. |
| AG-16 | ✅ | pyproject.toml [project.optional-dependencies].dev (lines ~ following :32) lists pytest/pytest-cov/hypothesis/ruff/mypy/import-linter/types-PyYAML — NO `mgf-common[standards]`. Core dep | AG-16 MUST: every project keeps the standards corpus resolvable to its agents by depending on `mgf-common[standards]` where agents/maintainers run the CLI (the dev/tooling extra suffices). This repo's dev extra omits the [standard — FIXED 2026-06-09: separate [standards] extra (mgf-common[standards]; OUT of [dev]) |
| AG-17 | ✅ | docs/memory/MEMORY.md present at repo root. | Memory anchor present; conforms. |
| AG-18 | ✅ | my_stuff/ in .gitignore; .githooks/prepare-commit-msg hook present. | Both components satisfied; conforms. |
| AG-19 | N/A | no runtime auto-memory store (~/.claude/projects/<slug>/memory/ absent) — nothing to track. | No store to track; N/A. |
| TM-01 | ✅ | UTC at boundaries — uses tz-aware `datetime`/UTC. |
| TM-02 | ✅ | ISO-8601/RFC-3339 wire format for datetimes. |
| TM-03 | N/A | no duration measurements with a wall clock (timeouts are not timed spans). |
| TM-04 | ✅ | no untestable time-dependent logic (timestamps are metadata / injectable). |
| TM-07 | N/A | UTC only; no IANA timezone-name usage. |
| TM-08 | ✅ | async sleeps use `asyncio.sleep`. |
| PF-01 | N/A | no performance budgets / perf tests. |
| PF-02 | N/A | no performance budgets / perf tests. |
| PF-03 | N/A | no performance budgets / perf tests. |
| PF-04 | N/A | no performance budgets / perf tests. |
| PF-05 | N/A | no performance budgets / perf tests. |
| PF-07 | N/A | no performance budgets / perf tests. |
| PF-08 | N/A | no performance budgets / perf tests. |
| OB-01 | N/A | no owned observability surface — consumes `mgf.common.observability` (OB rules bind the owner). |
| OB-02 | N/A | no owned observability surface — consumes `mgf.common.observability` (OB rules bind the owner). |
| OB-03 | N/A | no owned observability surface — consumes `mgf.common.observability` (OB rules bind the owner). |
| OB-04 | N/A | no owned observability surface — consumes `mgf.common.observability` (OB rules bind the owner). |
| OB-05 | N/A | no owned observability surface — consumes `mgf.common.observability` (OB rules bind the owner). |
| OB-07 | N/A | no owned observability surface — consumes `mgf.common.observability` (OB rules bind the owner). |
| OB-08 | N/A | no owned observability surface — consumes `mgf.common.observability` (OB rules bind the owner). |
| OB-09 | N/A | no owned observability surface — consumes `mgf.common.observability` (OB rules bind the owner). |
| OB-10 | N/A | no owned observability surface — consumes `mgf.common.observability` (OB rules bind the owner). |
| OB-11 | N/A | no owned observability surface — consumes `mgf.common.observability` (OB rules bind the owner). |
| NM-01 | ✅ | distribution name is hyphenated (NM-01). |
| NM-02 | ✅ | dotted import namespace `mgf.<sibling>` (NM-02). |
| NM-03 | ✅ | Codeberg slug hyphenated (NM-03). |
| GUI-01 | ✅ | imports no Qt at module level (GUI-01). |
| GUI-02 | N/A | no GUI (non-GUI library/CLI). |
| GUI-03 | N/A | no GUI (non-GUI library/CLI). |
| GUI-04 | N/A | no GUI (non-GUI library/CLI). |
| GUI-05 | N/A | no GUI (non-GUI library/CLI). |
| GUI-06 | N/A | no GUI (non-GUI library/CLI). |
| GUI-07 | N/A | no GUI (non-GUI library/CLI). |
| GUI-08 | N/A | no GUI (non-GUI library/CLI). |
| GUI-09 | N/A | no GUI (non-GUI library/CLI). |
| GUI-10 | N/A | no GUI (non-GUI library/CLI). |
| REL-10 | ✅ | federation member; participates in cohort-walk releases on a mgf-common pin break. |
| REL-11 | ✅ | released via the Phase A/B cohort-release flow. |
| REL-12 | N/A | binds the cohort Phase-A *agent's* pytest-denial handling, not a released sibling's code. |
| REL-13 | ✅ | releases pass the federation consistency gate (`mgf-fed registry --check`). |
| FB-05 | ✅ | cross-repo feedback flows through the `pending-feedback/<target>.md` outbox + the supervisor relay (`mgf-fed feedback`), never a direct edit (FB-05). |


---

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

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