Pagonic
Inspect ZIP archives before extraction writes files.
Pagonic is a security-aware Python CLI and library for untrusted or uncertain ZIP files. It produces deterministic risk reports, exposes CI-friendly policy checks, and gates extraction before files are written.
Inspect before you extract.
The intended workflow is visible in the demo:
inspectthe archive and produce a human, JSON, or Markdown report.verifythe report against an explicit risk threshold for CI or scripts.- Let
safe-extractapply the inspection gate before writing files.
Try it in 30 seconds
python -m pip install pagonic
pagonic inspect archive.zip --json
pagonic verify archive.zip --max-risk low
pagonic safe-extract archive.zip extracted --allow-risk low
Use the exit code from verify or safe-extract as the automation decision.
For a clean archive, verification reports risk level ok; risky or invalid
archives return a non-zero result before files are written.
- A core library for inspecting, writing, reading, and validating ZIP archives.
- A
pagoniccommand-line interface for inspect, verify, safe extract, and ZIP utilities. - An optional PyQt6 GUI launched with
pagonic-gui.
The repository targets the 0.5.x alpha release line. The import package
remains Pagonic for compatibility; the distribution name is pagonic. The
package is available on PyPI and
TestPyPI for publication checks. The
source and release artifacts remain available from the latest GitHub
release.
Project Story
Pagonic started more than a year ago as one of my earliest software-learning projects. Its first direction was much broader and more experimental: a ZIP/archive engine with compression, extraction, GUI ideas, benchmarking, and performance experiments.
After many iterations, I revised the project direction and narrowed the public scope into something clearer:
Pagonic is not trying to be another desktop archive manager. It is becoming a security-aware ZIP inspection and safe extraction toolkit.
The current 0.5.x release line builds on the first cleaned-up public
direction from v0.4.0 and the trustworthy automation surface established in
v0.5.0. It keeps the focused ZIP inspection, policy, and safe-extraction
behavior explicit for package users and CI workflows.
Pagonic is still evolving, but its purpose is now clearer: inspect first, extract safely.
Install
For normal CLI use, install the published package from PyPI:
python -m pip install pagonic
For an isolated command-line installation, either uv or pipx can manage the
tool environment:
uv tool install pagonic
pipx install pagonic
Verify the installation:
pagonic --version
On Windows, open a new terminal if the command is not recognized immediately
after installation. If pip warns that its Python Scripts directory is not
on PATH, add that directory to PATH or use the isolated uv/pipx install
above. If pip show pagonic points to an old or deleted checkout, reinstall
from the current repository root with python -m pip install --upgrade --force-reinstall -e ..
For local development, clone the repository first and install from the checkout.
For CLI-only use from a local checkout:
python -m pip install .
For local development:
python -m pip install -e .[dev,gui]
For CLI-only development with test dependencies:
python -m pip install -e .[dev]
Experimental performance helpers are optional and are not required by inspection or safe extraction:
python -m pip install -e .[performance]
The GUI is optional. If PyQt6 is not installed, pagonic-gui exits with a clear install message.
CLI Quick Start
pagonic --help
pagonic inspect suspicious.zip
pagonic inspect suspicious.zip --json
pagonic inspect suspicious.zip --markdown
pagonic verify release.zip
pagonic verify release.zip --max-risk medium
pagonic safe-extract upload.zip output/
pagonic safe-extract upload.zip output/ --dry-run
pagonic list archive.zip --tree
pagonic compress path/to/file.txt -o archive.zip
pagonic config list
Use inspect before extraction for untrusted ZIP files. safe-extract applies
the inspection gate before writing files, supports --dry-run, and refuses ZIP
entries that use unsupported compression methods.
Python API Quick Start
from Pagonic.core.formats.zip_writer import ZipWriter
from Pagonic.core.formats.zip_reader import ZipReader
writer = ZipWriter("archive.zip", compression_level=6)
writer.add_file("file.txt")
writer.finalize()
reader = ZipReader("archive.zip")
report = reader.inspect()
if report.risk_level in {"ok", "low"}:
reader.extract_all("output")
Project Layout
Pagonic/ Python package
tests/ pytest suite
docs/ public documentation
examples/ small runnable examples
pyproject.toml package metadata and tool config
Documentation
- Architecture
- User Guide
- Inspection Policy Contract
- Inspection JSON Schema Contract
- CI Integration
- Package Surface Audit
- Package Publishing
- 0.5 Migration Notes
- 0.5 Release Audit
- SARIF Evaluation
- ZipHandler Compatibility Policy
- Developer Guide
- 0.4 Migration Notes
- Roadmap
- Changelog
- Contributing
- Security Policy
- Code of Conduct
Contributing
Focused contributions are welcome, especially improvements to inspection determinism, security regression coverage, safe extraction policy, CI integration, and documentation. Read CONTRIBUTING.md, check the 0.5 roadmap, and use the issue templates before opening a pull request. Do not include private plans, local paths, secrets, generated archives, or benchmark output in public changes.
Risk Signals
Inspection reports are deterministic and do not use runtime AI. Current risk flags include:
| Flag | Severity | Meaning |
|---|---|---|
path_traversal |
high |
Entry contains .. path segments. |
absolute_path |
high |
Entry uses a POSIX absolute path. |
windows_drive_path |
high |
Entry looks like a Windows drive path. |
hidden_file |
low |
Entry basename starts with .. |
empty_filename |
medium |
Entry cannot be mapped to a useful safe path. |
too_many_files |
high |
Archive exceeds the configured file-count limit. |
large_uncompressed_size |
high |
Archive exceeds the configured uncompressed-size limit. |
high_compression_ratio |
high |
Entry expands much more than its compressed size. |
unsupported_compression_method |
medium |
Entry uses a ZIP method Pagonic does not currently support; safe-extract refuses it. |
crc_or_structure_error |
critical |
ZIP structure or CRC validation failed. |
suspicious_extension |
medium |
Entry has an executable or script-like extension. |
duplicate_filename |
high |
The same archive filename appears more than once. |
normalized_path_collision |
high |
Different names resolve to the same sanitized path. |
case_insensitive_collision |
high |
Names collide on case-insensitive filesystems. |
unicode_normalization_collision |
high |
Different Unicode spellings normalize to one path. |
symlink_entry |
high |
ZIP metadata marks the entry as a symbolic link. |
encrypted_entry |
high |
Entry contents cannot be validated by the current workflow. |
nested_archive |
low |
Entry appears to contain another archive; it is not recursively inspected. |
long_filename |
medium |
Entry name exceeds the configured review length. |
long_archive_comment |
low |
Archive comment exceeds the configured review length. |
pagonic inspect --json emits a stable alpha report with archive totals,
overall risk_level, top-level risk_flags, recommended_action, and per-entry
metadata. Entries preserve archive order and risk flags use a deterministic
catalog order. See the Inspection JSON Schema Contract
for canonical fields, compatibility aliases, ordering guarantees, and clean,
risky, and invalid report examples. pagonic inspect --markdown renders the
same inspection as a saved human-readable report.
Command Policy
Use inspect before extraction when the archive is untrusted. For automation,
verify returns exit code 0 only when the report is within --max-risk and
has no validation errors. safe-extract applies the same inspection gate before
writing files and supports --dry-run.
See the inspection policy contract for the exact clean/risky/invalid decision table, defaults, unsupported-method rule, and exit codes.
The older extract command remains as a compatibility command for trusted
archives. It uses secure path handling, but it is not an inspection policy gate;
use safe-extract for untrusted input. list and info are read-only display
commands and do not replace an inspection report.
Status
The current public release line is 0.5.x: an alpha-stage, test-backed
release with security-aware ZIP inspection, explicit policy gates, a synthetic
security regression corpus, gated safe extraction, core ZIP behavior, CLI
support, optional GUI packaging, MIT license, and CI-ready tests. The patch
line keeps the adoption surface focused on clear documentation and package
metadata; no new runtime feature is required for the core workflow.
Pagonic is not intended for production-critical automation yet and is not positioned as a general multi-format desktop archive manager. The next work is evidence-driven maintenance: collect real usage signals, expand the security corpus when new rules are added, and revisit deferred integrations only when a concrete consumer justifies them.
Metadata
Release files for pagonic 0.5.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| pagonic-0.5.1.tar.gz | 127.9 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| pagonic-0.5.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 242.8 kB
Release files / pagonic-0.5.1.tar.gz
| Download URL | pagonic-0.5.1.tar.gz |
|---|---|
| Size | 127.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
839710ce532e8618aa23a60ab1962c3f08355608ee08399e284d8336430c9a9e
|
|
BLAKE2b-256 checksum How to use checksums |
e0a2ed55e14fa68a8b6f8b34f20e6352e3f542a2eec9e6fa753fa49d004877da
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 3, 2026.
Transparency logRelease files / pagonic-0.5.1-py3-none-any.whl
| Download URL | pagonic-0.5.1-py3-none-any.whl |
|---|---|
| Size | 115.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
fc61bdc96e8209006c47fca3850827a912fd579739ba9d833fcdf1ab5d9ea95e
|
|
BLAKE2b-256 checksum How to use checksums |
955b9086d1868cadc34a41268cca6ee9ab609160c6cb2e4f324a9db270400d4e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 3, 2026.
Transparency log