# Layering contracts for mgf.common.
#
# SCOPE (read before assuming CI guards more than it does):
# the ONLY machine-enforced contract here is the federation-leaf
# direction (the outward-direction half of rule DP-01): consumers
# and siblings depend on mgf.common, never the reverse. mgf.common's
# INTERNAL module layering (which subpackage may import which) is
# NOT encoded as an import-linter contract — it is currently clean
# (acyclic) and is maintained by code review, not by `lint-imports`.
# Adding a module that violates internal layering will NOT fail CI;
# reviewers must catch it. See docs/standards/DESIGN_PRINCIPLES.md
# (rule DP-01) and the lift-readiness rule (LIFT-1) in
# docs/STANDARD_GAP.md.
#
# Run locally:      lint-imports
# Run in CI:        see .woodpecker.yml lint step
#
# Adding contracts? Each contract is phrased as a hard MUST NOT —
# import-linter fails the CI build on any violation. When adding a
# new rule, add a ``reason = ...`` comment so a future engineer
# (or AI) knows why it exists before deciding to relax it.

[importlinter]
root_packages =
    mgf.common
# Required because the contracts below name external packages
# (vmanager, mgf-* siblings, future consumer namespaces) as
# forbidden — without this flag, import-linter refuses to start.
include_external_packages = True

# ---------------------------------------------------------------------------
# Contract 1 — mgf.common is the federation leaf.
#
# Reason: mgf.common is the SHARED library that every consumer
# project depends on. The dependency direction MUST be one-way:
# consumers (vmanager, future siblings, future projects) depend
# on mgf.common, NEVER the reverse. Without this contract, a
# casual ``import vmanager.X`` inside mgf.common would create a
# cycle that breaks every other consumer.
#
# Federation policy (v0.4 Phase G1):
# Every consumer or sibling package gets a row below — independent
# downstream projects (vmanager and future open-source consumers)
# AND future siblings under the mgf.* PEP 420 namespace
# (mgf.qt / mgf.providers / mgf.cli when they materialize). The
# import direction always points OUT OF mgf.common; this contract
# forbids the reverse.
#
# Adding a new consumer? Add a row to ``forbidden_modules`` AND
# update docs/standards/DESIGN_PRINCIPLES.md to mention it as a
# known consumer of mgf.common.
#
# Why not a wildcard "deny all imports except deps"? import-linter
# doesn't support that directly. The pragmatic shape: enumerate
# known consumers + siblings. False negatives (a brand-new
# consumer not in this list) are caught by code review +
# integration testing on the consumer side.
# ---------------------------------------------------------------------------

[importlinter:contract:mgf-common-is-the-federation-leaf]
name = mgf.common does not import any consumer or sibling project
type = forbidden
source_modules =
    mgf.common
forbidden_modules =
    # Known consumer projects (top-level names — import-linter
    # accepts these as forbidden because they're top-level package
    # roots, not subpackages of an external root).
    vmanager
    plasmamapper
    inthewords
    # Federation siblings under the mgf.* PEP 420 namespace
    # (mgf.apiprobe ships as v0.1.0; future: mgf.cli, mgf.qt, etc.).
    #
    # NOTE: import-linter REJECTS subpackages of an external root
    # in `forbidden_modules` (it errors with "subpackages of
    # external packages are not valid"). Adding `mgf.apiprobe` here
    # fails with that exact error because `mgf` is the external
    # PEP 420 root.
    #
    # Workaround: the federation rule "mgf.common does not import
    # mgf.apiprobe / mgf.<sibling>" is enforced by code review +
    # consumer-side integration testing. mgf.apiprobe lives in its
    # own repo with its own CI; an accidental `import mgf.apiprobe`
    # added to mgf.common would be caught at PR review and at
    # apiprobe's CI when the next apiprobe release runs against
    # the latest mgf-common from PyPI.
    #
    # If a future import-linter version adds support for forbidding
    # subpackages of external roots, add the lines below + remove
    # this note.
    #
    #   mgf.apiprobe
    #   mgf.cli
    #   mgf.qt
    #   mgf.providers
    #   mgf.gui

[importlinter:contract:mgf-common-forbids-ui-frameworks]
# PR-01: a domain/common library MUST NOT import any UI framework. Enforced
# mechanically here (a clean tree without the gate is a comment, not a standard).
name = mgf.common does not import any UI framework (PR-01)
type = forbidden
source_modules =
    mgf.common
forbidden_modules =
    PySide6
    PyQt6
    PyQt5
    textual
    rich
    click
    flask
    fastapi
    django
    streamlit
    gradio
