Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 19 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,15 +52,26 @@ the terminal/command line as you normally would. This also lends to making cross
- [ ] Linux arm64 (64-bit)
- [ ] Linux arm (32-bit)
- [ ] macOS (arm64 / x86-64)
- [x] Windows x64 (64-bit)
- [ ] Windows x64 (64-bit)
- [ ] Windows x86 (32-bit )
- [ ] Windows arm64 (64-bit)

No platform row is currently receipt-backed. Per the promotion rule in
`AGENTS.md`, a row may be checked only with a qualification receipt
(exact Python version, OS/architecture, binary provenance, commands, and
test result). The Windows x64 row was unchecked on 2026-10-20 after the
receipt audit in
[`docs/planning/DECISION_WINDOWS_RECEIPTS_2026-10-20.md`](docs/planning/DECISION_WINDOWS_RECEIPTS_2026-10-20.md);
binary provenance states are tracked in
[`bin/PROVENANCE.md`](bin/PROVENANCE.md).

### Notes
- If you install this package using `git clone`, then all binary packages will be included.
This is not the case when using `pip install` as only the binary for the given system is
included; this allows for managing the various binaries easy through git versioning.
- Please also keep in mind, unless you are planning on bundling this module with your own
custom package, or want to contribute to the project there is little other reason to use
git to install it, because your python environement will not be able to locate it and
pathing will not be inherited.
- The PyPI wheel ships no binaries. On the default (safe) runtime, the
matching 7-Zip artifact is downloaded into a cache directory
(`~/.cache/py7zip` by default) and its sha256 is verified against
pinned digests before use; acquisition is explicit via
`download_binary()` or the first archive operation.
- A `git clone` of this repository includes the `bin/` tree itself
(see [`bin/INFO.md`](bin/INFO.md) and
[`bin/PROVENANCE.md`](bin/PROVENANCE.md)); the placeholder slots in
that tree are empty files and are not distributed.
52 changes: 26 additions & 26 deletions bin/INFO.md
Original file line number Diff line number Diff line change
@@ -1,37 +1,37 @@
# INFO
This directory contains the various platform specific binaries for the `py7zip` module.
This directory contains the platform-specific 7-Zip binaries referenced by
the `py7zip` module. The authoritative per-file inventory — including size,
digest, and provenance state — is [`PROVENANCE.md`](PROVENANCE.md); this
file describes the layout convention only.

## Structure
- The directory tree for binaries are broken down with the following convention:
- ./bin/{platform}/{type}/7za.{extension}
- ./bin/lin|mac|win/pc|arm/x86|x64
- Examples:
- Windows: ./bin/win/pc/x64/7za.exe
- Linux: ./bin/lin/arm/x86/7za
- Mac: ./bin/mac/any/7za
- Notes:
- Platforms consist of Lin/Mac/Win
- Extensions consist of .exe or None
- Types consist of PC/arm
- The directory tree for binaries follows this convention:
- ./bin/{platform}/{type}/{architecture}/7za{extension}
- platforms: `lin` | `mac` | `win`
- types: `pc` | `arm`
- architectures: `x64` | `x86` (pc), `x64` | `x32` (arm)
- extension: `.exe` (windows) or empty (linux, mac)
- Examples (all present on disk today):
- Windows: ./bin/win/pc/x64/7za.exe
- Linux: ./bin/lin/arm/x32/7za
- Mac: ./bin/mac/any/7za

## Windows Binaries
- bin/win/arm/x64/7za.exe
- bin/win/arm/x86/7za.exe
- bin/win/pc/x64/7za.exe
- bin/win/pc/x86/7za.exe
## On-disk inventory

## Linux Binaries
- bin/lin/arm/x32/7za
- bin/lin/arm/x64/7za
Non-empty (cataloged by `py7zip/platforms.py`; provenance in
[`PROVENANCE.md`](PROVENANCE.md)):
- bin/lin/pc/x64/7za
- bin/lin/pc/x86/7za

## Mac OS Binaries
- bin/lin/arm/x64/7za
- bin/lin/arm/x32/7za
- bin/win/pc/x64/7za.exe
- bin/win/pc/x86/7za.exe
- bin/mac/any/7za
- bin/mac/arm/x32/7za

Empty placeholders (0 bytes, not cataloged, not distributed):
- bin/win/arm/x32/7za
- bin/win/arm/x64/7za
- bin/mac/arm/x64/7za
- bin/mac/arm/x86/7za
- bin/mac/pc/x64/7za
- bin/mac/pc/x86/7za

### Notes
- TBD: Unix, Dos, Pocket PC, etc.
95 changes: 95 additions & 0 deletions bin/PROVENANCE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
# Artifact provenance ledger

One row per non-empty binary under `bin/`, plus the empty placeholder
slots. This ledger is the inventory of record for `bin/` (it supersedes
the older, conflicting lists in `INFO.md`, which now describes layout
only).

Conventions:

- **Anchored** = byte-identity (sha256) to a specific upstream-published
artifact, with URL and digest recorded.
- **UNPROVEN** = no upstream anchor has been recorded for the file. The
row states what *is* known (static format and banner evidence). An
UNPROVEN row is not a claim of innocence or of support; it is an open
item for the overhaul plan (OVH-02 rows; the darwin row is adjudicated
by gate OVH-29 / D-OVH-6).
- Banner lines are static `strings` output. **No bundled binary was
executed** to produce this ledger.
- "Introduced" is the commit that first added the file to this
repository; the upstream source of every file was never recorded and
is treated as unrecorded unless an anchor says otherwise.
- Checks re-run on **2026-10-20** (Fedora Linux x86-64 NVMe checkout of
branch `agent/py7zip-overhaul-20261019`, then equal to `origin/main`
`a06615f`) unless marked otherwise.

Summary counts: 7 non-empty artifacts (one anchored, six UNPROVEN), 6
empty placeholders (not distributed). Per `AGENTS.md`, no
platform-support claim may be made from this ledger alone.

## Non-empty artifacts

| Artifact | Size (bytes) | sha256 | Static format | Embedded banner (static `strings`) | Upstream version | Provenance | Introduced |
|---|---|---|---|---|---|---|---|
| `bin/lin/pc/x64/7za` | 2,837,048 | `12ef12519899ecda8ba59940d7f25a3f4818c97693538d49e894e6b783fb3081` | ELF x86-64, dynamically linked (`/lib64/ld-linux-x86-64.so.2`) | `7-Zip (z) 24.00 (x64) : Copyright (c) 1999-2024 Igor Pavlov : 2024-01-30` | 24.00 | **Anchored** — see row note A | `1fabd26` (2024-02-24) |
| `bin/lin/pc/x86/7za` | 3,139,200 | `ca0950c6d4b6e4ed2c7d0d1759b2beb68aecaf95ed31d9e5c1ae9faa914c37b9` | ELF i386, dynamically linked (`/lib/ld-linux.so.2`) | `7-Zip (z) 24.00 (x86) : Copyright (c) 1999-2024 Igor Pavlov : 2024-01-30` | 24.00 | UNPROVEN | `1fabd26` (2024-02-24) |
| `bin/lin/arm/x64/7za` | 2,428,216 | `271f123d64fb339f3011388005ff781958e4c17b9eb781e4d7a7b38712808a41` | ELF aarch64, dynamically linked (`/lib/ld-linux-aarch64.so.1`) | `7-Zip (z) 24.00 (arm64) : Copyright (c) 1999-2024 Igor Pavlov : 2024-01-30` | 24.00 | UNPROVEN | `1fabd26` (2024-02-24) |
| `bin/lin/arm/x32/7za` | 1,519,768 | `1414d731e764b969c22dae77d3948c6f0d1fca7b33eb7a16d016038e4e8ea753` | ELF ARM (EABI5, armhf), dynamically linked (`/lib/ld-linux-armhf.so.3`) | `7-Zip (z) 24.00 (armt) : Copyright (c) 1999-2024 Igor Pavlov : 2024-01-30` | 24.00 | UNPROVEN | `1fabd26` (2024-02-24) |
| `bin/win/pc/x64/7za.exe` | 1,314,816 | `827f88db392fbb679ca0dcf0818f32e74b59242061d0e6bc05bac9c672bbde51` | PE32+ console, x86-64 | `7-Zip (a) 24.01 (x64) : Copyright (c) 1999-2024 Igor Pavlov : 2024-01-31` | 24.01 | UNPROVEN | `1fabd26` (2024-02-24) |
| `bin/win/pc/x86/7za.exe` | 841,216 | `4721caf434de02b9aeb80b930702bbca75a1d54a5308c3445ec0db0778cfe693` | PE32 console, i386 | `7-Zip (a) 24.01 (x86) : Copyright (c) 1999-2024 Igor Pavlov : 2024-01-31` | 24.01 | UNPROVEN | `1fabd26` (2024-02-24) |
| `bin/mac/any/7za` | 5,792,768 | `c76d80526586c039e11d9d2ea8fe02324798c5082711178304b5060565859742` | Mach-O universal (x86_64 + arm64) | `7-Zip (z) 24.00 (x64)` and `7-Zip (z) 24.00 (arm64)`, both `: 2024-01-30` | 24.00 (both slices) | UNPROVEN — adjudicated by gate **OVH-29** (D-OVH-6) | `1fabd26` (2024-02-24) |

Row note A — the anchor for `bin/lin/pc/x64/7za`: the file is
byte-identical (sha256 above) to the official dynamic `7zz` inside
`7z2400-linux-x64.tar.xz`, recovered from the Wayback capture
(`web.archive.org/web/20240221221419/…`) of the official URL
`https://7-zip.org/a/7z2400-linux-x64.tar.xz` (pruned from the live
site today; upstream published no digest for 24.00-era assets). The
archived tarball's sha256 was computed during the 2026-10-11 probe as
`3bb85b8209a34e24e2938f0434fb0866e9a5750463478c82b977ca7ad49b90ff`
(trust-on-first-use caveat: the digest is ours, upstream published
none). The bundled file's digest was re-verified against this row on
2026-10-20; the archived tarball itself was not re-downloaded on that
date.

Row notes for the UNPROVEN rows:

- `bin/lin/pc/x86`, `bin/lin/arm/x64`, `bin/lin/arm/x32`: same-era
official-format banners, no upstream anchor recorded. The 24.00-era
archival procedure of the overhaul handoff (probe V19) has not been
run for these rows; a Wayback availability re-check on 2026-10-20 was
rate-limited (HTTP 429) and produced no new evidence.
- `bin/win/pc/x64`, `bin/win/pc/x86`: version evidence is 24.01, one
patch after the other Linux/mac rows, and the banner brand is
`7-Zip (a)` rather than the console builds' `7-Zip (z)`. Anchoring
these requires the 24.01-era Windows distribution (installer or
`-extra` package); that source decision is owned by gate OVH-07
(D-OVH-2) and must not be preempted here.
- `bin/mac/any`: version-evidenced 24.00 in both slices; provenance
UNPROVEN. No archived copy of the official 24.00 mac asset was
located as of the 2026-10-11 probe (V19); the availability re-check
belongs to gate OVH-29 at decision time.

## Placeholder slots (empty, not distributed)

All six files below are 0 bytes (sha256 of empty input
`e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855`).
The artifact catalog (`py7zip/platforms.py`) intentionally carries no
entry for them; requests for these hosts resolve to a typed
`UnsupportedPlatformError`.

- `bin/win/arm/x32/7za`
- `bin/win/arm/x64/7za`
- `bin/mac/arm/x64/7za`
- `bin/mac/arm/x86/7za`
- `bin/mac/pc/x64/7za`
- `bin/mac/pc/x86/7za`

## Consistency checks

- `find bin -type f -size +0c | sort` (binaries only) yields exactly
the seven artifacts tabled above — one ledger row each, re-verified
2026-10-20.
- All seven digests and sizes above match
`ArtifactCatalog._ARTIFACTS` (`py7zip/platforms.py`) exactly,
re-verified 2026-10-20.
21 changes: 14 additions & 7 deletions docs/FEATURES.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,19 @@
Reference documentation that details the features of this module as well as 7zip.

## Py7zip
- Simplified "point-in-time" backups and full/incremental schemas using snapshots
- Simplifies lessor known features of 7zip. Such as full, differential, incremental backups, etc.
- Comprehensive documentation through online wiki pages (using standard markdown).
- Cross platform support for Windows, Linux, and Mac.
- Native "Pythonic" logic removes need for additional libraries or CLI executing.
- Uses '7za' compiled library for compatability, Performance, and Reliability.
- Backup helper methods are planned but not implemented: `full` is a no-op,
`incremental` is a no-op, `differential` is a no-op, and `snapshot` is a
no-op in PyPI 0.6.2 and on the current main line (see
`docs/planning/COMPATIBILITY.md`).
- Documentation under `docs/` (a GitHub wiki is planned).
- Binaries are cataloged for Linux, Windows, and macOS hosts; other hosts
are refused with a typed error. Qualified platform-support claims require
receipts per `AGENTS.md`; see the platform checklist in `README.md` and
`bin/PROVENANCE.md`.
- Wraps a 7-Zip command-line binary from Python: the default runtime builds
an argument vector and runs it without a shell.
- Uses 7-Zip console binaries (`7za`) rather than reimplementing archive
formats in Python.
- Lightweight, being under a few megabytes in size (varies by platform).

## 7-zip Features (Source: https://www.7-zip.org):
Expand All @@ -25,4 +32,4 @@ Reference documentation that details the features of this module as well as 7zip
- Strong AES-256 encryption in 7z and ZIP formats
- Self-extracting capability for 7z format
- Powerful command line version
- Localizations for 87 languages (not currently implimented)
- Localizations for 87 languages (not currently implemented)
67 changes: 31 additions & 36 deletions docs/SETUP.md
Original file line number Diff line number Diff line change
@@ -1,46 +1,41 @@
# SETUP
This document outlines the steps needed to contribute to this project. A workflow is
already established and several steps automated, and while these steps can still be
done manually, for the purpose of consistancy and ease please use the outlined best
practices found here.
This document outlines the steps needed to contribute to this project.

## Prerequisites
- Python within the supported range (`requires-python` in `pyproject.toml`)
with `pip`
- A local clone of this repository

### PyPi Setup
These steps only need to be taken if you have access to the root PyPi package library
and account.
## Build and test locally
```shell
# Run the offline test suite
python -m pytest tests -p no:cacheprovider

- Steps
- Login to PyPi and create an API key
- Create an environment variable called PYPI_API_KEY
- Copy the API key into the User Environment variable

## Publishing Changes
The "Push.bat" script is currently set to dynamically commit changes, include
an auto-commit message if none is provided, build and publish updates made the
PyPi packages automatically based on the PYPI_API_KEY, and cleanup. The build
and PyPi publishing will only occur on version change, which is dynamically
reflected by simply updating the CHANGELOG.md file. Standard non-version commits
will be ignored.
# Build a wheel into a local scratch directory
python -m pip wheel . --no-deps -w dist/

`push -m "{Message}"`

### Manual Publishing Steps
The following commands are dynamically ran by the "push.bat" file, in the case
the repo version is higher, and the PYPI_API_KEY envernmnet variable is set,
then publish changes to PyPi project. However, this is how it would be done
manually if needed.

```pycon
# Builds Python Packages
python setup.py sdist bdist_wheel

# Uploads Python Packages to PyPi
twine upload -u api -p %PYPI_API_KEY% dist/*
# Inspect the installed package version
pip show py7zip
```

### Get py7zip Versions
- `pip show py7zip`
The test suite must pass with no network access; it fails loudly if any
test attempts to open a socket.

## Publishing changes (maintainers)
Publishing is automated through GitHub Actions
(`.github/workflows/publish.yml`):

- A publish run is triggered by publishing a GitHub **release**. The
workflow builds the package with `python -m build`, validates it with
`twine check`, verifies that the release tag matches the `version` in
`pyproject.toml`, and uploads to PyPI using **trusted publishing**
(OIDC). No API token is stored in the repository.
- `workflow_dispatch` runs exist for rehearsal only: they build and run
`twine check` but never publish.
- To cut a release: update `version` in `pyproject.toml` and the release
notes under `.github/CHANGELOG.md`, then create the matching release
tag and publish the GitHub release. Never reuse a version or tag that
has already been published anywhere; the version-selection rules live
in `docs/handoffs/2026-10-11-py7zip-overhaul.md` (OVH-21).

## Versioning
Versioning changes are based on {Major}.{Minor}.{Bug}.
37 changes: 27 additions & 10 deletions docs/USAGE.md
Original file line number Diff line number Diff line change
@@ -1,19 +1,36 @@
# USAGE

## Example Python script:
import py7zip
from py7zip.py7zip import Py7zip

# Sets up binary for the system if it does not already exist and assigns the 7zip class to 'z'
z = py7zip.Py7zip()
src = "path/to/zipfile"
dst = "path/to/output/directory" # Usually contains a .zip extension
options = "" # Optional
# Constructing the wrapper detects the host platform. It downloads
# nothing and starts no process until you request an archive operation.
z = Py7zip()

# Compress source file or directory to destination
z.compress(src, dst, options)
src = "path/to/source" # file or directory to archive
archive = "path/to/output/archive.7z"
outdir = "path/to/output/directory"

# Decompress source archive back to destination directory
z.decompress(dst, src, options)
# Optional and explicit: acquire the checksum-verified binary for this
# platform into the cache now. If skipped, the first archive operation
# acquires it on demand.
z.download_binary()

# Compress source file or directory into the destination archive.
# Returns an ArchiveResult; check .success / .returncode.
result = z.compress(src, archive)

# Decompress an archive back into the destination directory.
result = z.decompress(archive, outdir)

# Options are individual arguments, not a shell string; passing a
# plain string raises TypeError on the default runtime.
result = z.compress(src, archive, ("-mx9",))

The default runtime is the safe runtime: it executes 7-Zip with an
argument list (never a shell), verifies the downloaded binary's sha256
digest against pinned values, and rejects archive members that would
escape the extraction directory.


## 7zip Usage (Command Line Arguments; aka "Options")
Expand Down
Loading
Loading