python -m venv .venv
.\.venv\Scripts\activate
python -m pip install --upgrade pip
python -m pip install -e .[dev,gui]On Unix-like shells, activate with source .venv/bin/activate.
Run the default suite:
python -m pytest -qRun comprehensive tests:
python -m pytest -q --comprehensiveRun coverage:
python -m pytest --cov=Pagonic --cov-report=term-missingpython -m build
python -m pip checkFor a wheel-installed CLI smoke check after building:
python -m pip install --force-reinstall --no-deps dist/*.whl
pagonic --version
pagonic inspect --helpDo not commit bytecode, coverage files, local archives, editor settings, virtual environments, or old planning logs. Public documentation should live in README.md, CHANGELOG.md, and docs/.
Prefer the inspection service for untrusted archives:
from Pagonic import ZipReader, ZipWriter, inspect_archive
report = inspect_archive("archive.zip")
reader = ZipReader("archive.zip")The report is JSON-serializable through to_dict() and includes archive-level
size totals, per-entry metadata, risk flags, warnings, errors, and a summary
risk level. ZipWriter remains the public creation API. CLI commands such as
inspect, verify, and safe-extract should reuse this service instead of
duplicating path or ZIP bomb checks.
ZipHandler is retained as a compatibility facade through the 0.5 line. Its
compress() and decompress() methods delegate to ZipWriter and
ZipReader; new features must be added to those public APIs first rather than
to the facade. The facade's 0.5 no-warning policy and future migration path are
documented in the ZipHandler Compatibility Policy.
The serialized report declares schema_version: "1". The canonical report
keys are:
- Archive report:
archive_path,file_count,total_compressed_size,total_uncompressed_size,global_compression_ratio,risk_level,risk_flags,warnings,errors,recommended_action,entries. - Entry report:
original_name,normalized_name,safe_name,compressed_size,uncompressed_size,compression_method,compression_ratio,crc32,risk_flags.
The early-alpha aliases compression_ratio at archive level and filename,
safe_path in entries remain serialized for compatibility. New consumers
should use global_compression_ratio, original_name, normalized_name, and
safe_name.
The complete schema versioning, alias migration, array ordering, and report example contract is documented in the Inspection JSON Schema Contract. Keep changes to serialized fields and ordering synchronized with that document and its schema regression tests.
The reader and writer keep returning ordinary dictionaries at runtime for
compatibility, while their stable result shapes are available as public
TypedDict contracts:
from Pagonic import ArchiveInfo, ExtractionResult
archive: ArchiveInfo = reader.get_archive_info()
extraction: ExtractionResult = reader.extract_all("output")ZipWriter.finalize() returns CompressionStats, and
ZipReader.get_file_info() returns FileInfo | None. These types describe
the existing mappings; they do not add a runtime wrapper or change the JSON
report schema.
Risk flag metadata lives in RISK_CATALOG. Each catalog entry has an id,
title, severity, explanation, and recommended_action. Keep new report
renderers and CLI commands attached to that catalog instead of hardcoding
parallel risk descriptions.
CLI policy defaults:
verifypasses only archives at or below--max-risk lowand without validation errors.safe-extractallows up to--allow-risk mediumby default, refuses validation errors, and supports--dry-runfor decision checks without writing files.safe-extractalso refusesunsupported_compression_methodarchives before extraction, even when the selected risk threshold would otherwise allowmedium, because unsupported methods cannot be extracted safely by Pagonic.
The complete decision table, command boundaries, and exit-code contract live in the inspection policy contract. Keep policy tests and CLI behavior synchronized with that document when changing thresholds or validation handling.
The copyable CI integration guide demonstrates the same exit-code contract for GitHub Actions, Bash, and PowerShell workflows.
- Keep the import package name
Pagonicuntil a planned migration introduces lowercase compatibility. - Keep PyQt6 behind the
guioptional dependency. - Keep
numpyand the optional performance stack behind theperformanceextra; the inspector and safe-extract paths must not require it. ConfigManagercreates isolated default state.get_recent_files()andto_dict()return copies, so callers cannot mutate persisted configuration accidentally through a returned list or mapping.- Prefer focused tests for behavior changes and run the full suite before publishing changes.
- Avoid adding claims about acceleration or automation unless the code and tests support them.
- Keep the public product direction focused on ZIP inspection, verification, reporting, and safe extraction rather than general archive-manager competition.
- See 0.4 migration notes before moving new code toward the next public API surface.