Skip to content

refactor!: layer the argumentation package into subpackages (0.3.0)#1

Merged
ctoth merged 23 commits into
mainfrom
reorg/0.3.0-layered-subpackages
May 24, 2026
Merged

refactor!: layer the argumentation package into subpackages (0.3.0)#1
ctoth merged 23 commits into
mainfrom
reorg/0.3.0-layered-subpackages

Conversation

@ctoth
Copy link
Copy Markdown
Owner

@ctoth ctoth commented May 23, 2026

TL;DR

The flat 56-module argumentation package is reorganized into ten layered subpackages with the import-layer DAG enforced in CI by import-linter. Breaking change — every import path is new (argumentation.dungargumentation.core.dung, etc.); see CHANGELOG.md for the full old→new table. Ships as 0.3.0.

What changed

Structure

argumentation/
  core/                dung labelling preference solver_results preprocessing
                       scc_recursive bipolar accrual
  structured/aspic/    aspic aspic_encoding aspic_incomplete subjective_aspic
                       datalog_grounding
  structured/aba/      aba aba_sat aba_asp aba_decomposition aba_incremental
                       aba_preprocessing aba_route_policy aba_telemetry
  frameworks/          adf setaf setaf_io caf vaf vaf_completion partial_af
                       practical_reasoning
  gradual/             gradual dfquad equational gradual_principles
                       llm_surface sensitivity
  ranking/             ranking ranking_axioms weighted matt_toni
  probabilistic/       probabilistic probabilistic_components
                       probabilistic_treedecomp epistemic
  dynamics/            enforcement dynamic af_revision approximate optimization
  interop/             iccma
  solving/             af_sat sat_encoding backends solver solver_differential
                       iccma_cli
  solver_adapters/     (unchanged: clingo iccma_aba iccma_af)
  semantics.py         (top-level facade, unchanged location)
  encodings/           (.lp data, unchanged)

Breaking changes

  • Every import path changed. Full old→new table in CHANGELOG.md.
  • argumentation.__all__ removed; argumentation/__init__.py collapsed to a one-line docstring. import argumentation no longer eagerly imports submodules — import what you need explicitly.
  • The iccma-cli console-script entry point moved to argumentation.solving.iccma_cli. No surface change for users running iccma-cli; relevant if you invoked python -m argumentation.iccma_cli — use python -m argumentation.solving.iccma_cli instead.

Architecture is now machine-enforced

A [tool.importlinter] layers contract in pyproject.toml pins the import DAG:

core
  < structured.aspic | frameworks | gradual | ranking
  < structured.aba | probabilistic | dynamics
  < interop
  < solver_adapters
  < solving
  < semantics

CI runs uv run lint-imports. Two function-local solver_adapters.clingo edges (aspic_encoding and aba_asp, both conditional clingo-adapter loads) are the only sanctioned ignore_imports. The architecture stopped being a story and became a contract.

One pre-existing correctness fix included

Mid-reorg, a Hypothesis property test surfaced a latent aba_sat bug: a required assumption forced OUT by simplify_aba KeyError'd at the residual solver. Fixed at commit 5c53816 per Bondarenko et al. 1997 (Def 2.2 p.70 + Thm 6.4 p.90): a fixed_out assumption is in no preferred extension, so a query requiring one is unsatisfiable → returns None. Oracle-verified on 400 generated examples. Adds a focused regression test and a Hypothesis property test of the invariant.

Commit chain (18 commits)

# hash what
S1 e79632c test: add layer-architecture contract test
C0 98e7015 scaffold layered subpackages
C1 88deb13 move core layer
C2 7833f6b move ASPIC+ layer
X 5c53816 fix(aba-sat): required fixed_out assumption is unsatisfiable
C3 8b81abe move frameworks layer
C4 6a9d395 move gradual layer
C5 913c328 move ranking layer
C6 0d4b6ff move ABA layer
C7 601eb11 move probabilistic layer
C8 d82c484 move dynamics layer
C9 68dda7e move iccma into interop
C10 9ecdbda move solving layer
C11 9644236 enforce layered architecture with import-linter
C12 bab4bac document the layered layout and release 0.3.0
4c80f07 build: drop redundant encodings/ force-include
d06a5ce docs: add codex reorg review report
59f3f91 fix: update stale argumentation.aba_asp path in encodings comment

Each layer commit was independently gated: full suite green, pyright src clean, no missing imports. Per-commit reports live under reports/reorg-c*.md.

Verification

  • uv run pytest -q2824 passed, 3 skipped, 1 xfailed, 0 failed, 0 collection errors
  • uv run pyright src0 errors
  • uv run lint-imports2 contracts kept, 0 broken
  • uv build — wheel formal_argumentation-0.3.0 + sdist with all 12 subpackages, no warnings
  • Independent Codex review (reports/codex-review-reorg.md) — verdict MERGE-READY after the one shipped-comment fix that is now applied
  • Final independent verifier (reports/reorg-verify-final.md) — verdict MERGE-READY
  • Comprehensive straggler grep across src/ tests/ bench/ tools/ — zero surviving flat-path imports

Downstream impact

A precise migration plan for propstore (the primary consumer) is at propstore/notes/argumentation-0.3.0-migration.md: 296 import lines across 104 files, 2 files needing structural rewrites (their from argumentation import <bare> patterns are affected by __all__ removal). Not executed by this PR; awaits a separate propstore-side update.

Migration recipe for users

Update imports per the CHANGELOG.md old→new table. Anything using argumentation.__all__ or the import argumentation; argumentation.X attribute-access pattern must be rewritten to explicit submodule imports.

Not included / follow-ups

  • The untracked scripts/ directory contains two files with old flat imports (probe_sensitivity_delta_sign.py, verify_sensitivity_expectations.py). Out of this PR's scope; untracked.
  • 0.3.0 is not published to PyPI by this PR. Publishing is a separate explicit step.

ctoth added 23 commits May 22, 2026 10:47
Encodes the package's import-layer DAG as an executable contract: every module carries a layer rank, and no module may import a higher layer (bar two sanctioned function-local clingo-adapter edges). Makes the architecture CI-enforced rather than convention.
Create the empty core/, structured/{aspic,aba}/, frameworks/, dynamics/,
interop/, solving/ subpackages and the full tests/ mirror. Collapse
argumentation/__init__.py to a docstring (the 41-module eager re-export
and argumentation.__all__ are removed). Remove the superseded flat-layout
layer test. The gradual/, ranking/, probabilistic/ subpackage directories
are deferred to their layer commits (they collide with same-named flat
modules until those modules move). No modules move in this commit.
git mv dung, labelling, preference, solver_results, preprocessing,
scc_recursive, bipolar, accrual into argumentation/core/. Rewrite every
importer across src/, tests/, bench/, tools/. Move the core-layer test
files into tests/core/. No behavior change.
git mv aspic, aspic_encoding, aspic_incomplete, subjective_aspic,
datalog_grounding into argumentation/structured/aspic/. Rewrite every
importer across src/ and tests/. Move the ASPIC+ test files into
tests/structured/aspic/. No behavior change.
…rash

decomposed_prefsat_extension subtracted only fixed_in from the required
assumption set, so a required assumption forced OUT by simplify_aba leaked
into the residual solver, which has no SAT variable for it -> KeyError.
A fixed_out assumption is in no preferred extension (Bondarenko et al.
1997, Def 2.2 p.70 + Thm 6.4 p.90): every preferred set is conflict-free
and contains the well-founded set, whose theory derives the assumption's
contrary. So a query requiring a fixed_out assumption is unsatisfiable;
short-circuit to that answer. Adds a focused regression test and a
property test of the invariant.
git mv adf, setaf, setaf_io, caf, vaf, vaf_completion, partial_af,
practical_reasoning into argumentation/frameworks/. Rewrite every importer
across src/ and tests/. Move the framework test files into
tests/frameworks/. Delete the vestigial test_adf export test C0 left as a
pass-body. No behavior change.
git mv gradual, dfquad, equational, gradual_principles, llm_surface,
sensitivity into argumentation/gradual/. Rewrite every importer across
src/ and tests/. Move the gradual test files into tests/gradual/. Delete
vestigial package-attribute export tests. No behavior change.
git mv ranking, ranking_axioms, weighted, matt_toni into
argumentation/ranking/. Rewrite every importer across src/ and tests/.
Move the ranking test files into tests/ranking/. No behavior change.
git mv aba, aba_sat, aba_asp, aba_decomposition, aba_incremental,
aba_preprocessing, aba_route_policy, aba_telemetry into
argumentation/structured/aba/. Rewrite every importer across src/ and
tests/. Move the ABA test files into tests/structured/aba/. No behavior
change.
…(C7/12)

git mv probabilistic, probabilistic_components, probabilistic_treedecomp,
epistemic into argumentation/probabilistic/. Rewrite every importer across
src/ and tests/. Move the probabilistic test files into
tests/probabilistic/. No behavior change.
git mv enforcement, dynamic, af_revision, approximate, optimization into
argumentation/dynamics/. Rewrite every importer across src/ and tests/.
Move the dynamics test files into tests/dynamics/. No behavior change.
git mv iccma into argumentation/interop/. Rewrite every importer across
src/ (including solver_adapters/) and tests/. Move the ICCMA interop test
files into tests/interop/, fixing repo-root path depth in the two
manifest-reading tests. No behavior change.
git mv af_sat, sat_encoding, backends, solver, solver_differential,
iccma_cli into argumentation/solving/. Rewrite every importer across src/
and tests/. Move the solving test files into tests/solving/. Update the
iccma-cli console-script entry point to argumentation.solving.iccma_cli.
No behavior change.
Add import-linter as a dev dependency and a [tool.importlinter] layered
contract pinning the package import DAG: core < structured.aspic /
frameworks / gradual / ranking < structured.aba / probabilistic /
dynamics / interop < solver_adapters < solving < semantics. Two
function-local clingo-adapter edges are the sanctioned ignore_imports.
Add `uv run lint-imports` to CI. The architecture is now machine-checked.
Rewrite docs/architecture.md, README.md, and CONTRIBUTING.md to the
layered import paths; add a layered-architecture section and a package
-layout contributor note. Update tests/test_docs_surface.py expected
paths to match. Add CHANGELOG.md with the 0.3.0 breaking-change entry and
the full old->new path table. Bump version to 0.3.0.
The [tool.hatch.build.targets.wheel.force-include] entry mapping
src/argumentation/encodings was double-covered by the recursive
packages = ["src/argumentation"] inclusion, producing a "Duplicate name"
warning on uv build. Remove the redundant block; the wheel still ships
encodings/*.lp via the package inclusion.
src/argumentation/encodings/aba_com_incremental.lp shipped a comment
naming the pre-reorg path argumentation.aba_asp.encode_aba_theory. The
0.3.0 layered path is argumentation.structured.aba.aba_asp.encode_aba_theory.
Caught by Codex review of the reorg.
@ctoth ctoth merged commit d7bb234 into main May 24, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant