Skip to content

P1: Add Python import-cycle and layer-policy parity #293

Description

@tomdps

Parent

Tracking parent #291; epic #243. This is one vertical implementation slice.

Goal

Bring Python import policy to the accepted TypeScript surface: deterministic cycle findings plus configurable layer rules, while preserving graph-core as the sole Python import parser/resolver and exact hypothetical after-state behavior.

Dependencies

Required behavior

  1. Extend python.import-graph to diagnose deterministic directed cycles from canonical repo-confined IMPORTS_FROM facts in addition to retained missing-edge validation. Do not add a TypeScript-side Python parser or resolve import text in validation.
  2. Add python.import-layer-rules with the same user model as the accepted TypeScript layer check: named from/to/optional fromNot path rules, deterministic wildcard semantics, error severity, explicit empty-policy behavior, and Python-specific handling for imports guarded only by typing.TYPE_CHECKING.
  3. Graph-core must attach contract-bound provenance sufficient to distinguish imports proven type-checking-only from runtime imports, including supported direct and aliased TYPE_CHECKING forms. Ambiguous/dynamic/control-flow cases remain runtime-visible or explicitly unsupported; validation may never guess from source text.
  4. Consume the exact shared graph session owned by the ValidationFileView; all created/updated/deleted overlays, source/stub/package/namespace layouts, project boundaries, and introduced-mode fingerprints must use the same after-state edges.
  5. Cycle canonicalization must collapse rotations, preserve direction, report each strongly connected cycle deterministically, avoid self-edge fabrication, and keep identical fingerprints across graph ordering and platforms. The finding path is stable and in-repo.
  6. Layer rules apply only to resolved repo import edges whose endpoints are inside the selected canonical Python project/source universe. Cross-project, unresolved, namespace, stub/runtime-peer, and generated/private/cache cases produce explicit supported/ignored/degraded evidence rather than accidental matches.
  7. Add Python policy config parsing/composition, manifests, check ids, contracts/schema if edge attributes change, graph handshake capability, fixtures, reporting/ASP/status/measure projections, docs, package exports, and packed-install coverage together.
  8. Missing/stale/malformed/incomplete graph evidence is a required infrastructure/non-pass result for exact Python evaluation. No graph absence, missing type-only metadata, or empty edge set may be reported as a clean policy pass when source imports exist.

Acceptance criteria

  • Two/three-node cycles, multiple/disjoint/overlapping cycles, acyclic diamonds, duplicate imports, relative levels, package __init__, namespace packages, .pyi peers, and overlay-created/broken/resolved cycles are deterministic.
  • Layer rules cover exact and % wildcard paths, fromNot, multiple named rules, same-name modules in different projects, src/flat layouts, relative/absolute imports, re-exports, invalid/duplicate config, no rules, and introduced mode.
  • Runtime imports, if TYPE_CHECKING, typing.TYPE_CHECKING, aliased imports, nested/ambiguous conditions, and unsupported dynamic imports have explicit tested policy behavior; the graph owns the classification.
  • Graph status/handshake, edge serialization/store/query, contracts/schema/fixtures, and exact-state materialization preserve any new import attributes without breaking TypeScript/Rust consumers.
  • Missing graph, stale graph, failed exact build, incomplete edges, malformed attributes, timeout/resource failure, and out-of-root endpoints fail/degrade honestly with no empty success.
  • Source, config, lockfiles, environment, caches, and generated provider trees remain unchanged; all temporary graph roots are removed.

Observable outcomes

  • PY_IMPORT_GRAPH_CYCLE identifies one canonical directed cycle.
  • PY_IMPORT_LAYER_RULE identifies the named policy rule and resolved from/to paths.
  • Clean success includes exact graph identity/edge coverage and selected project provenance.

Non-goals

Verification

  • npm run build
  • focused graph-core Python import extraction/store/protocol tests
  • focused validation-python import graph/layer/policy/overlay tests
  • contracts/schema/conformance/reporting/ASP tests
  • npm run lint
  • npm run rust:check
  • npm run pack:check
  • configured zeroshot cmdproof prove opcore-ci

Attach exact graph-core artifact/version, project/source universe, normalized edges/diagnostics, overlay before/after proof, cleanup, and packed-install evidence.

Execution rule

Implement only after a JIT review against current dev. Keep exactly one implementation run active. PR base is dev; require green checks, clean scoped diff, merged PR, closed child, #291/#243 checklist update, focused reproductions, and opcore-ci proof before advancing. Do not claim Python readiness/parity, ASP authority, old-tool replacement, security/SAST, all-stack support, automatic fixes, or a blended score.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions