From 42dd2b7910911c2934cbb98483aa38a039881011 Mon Sep 17 00:00:00 2001 From: Micheal Kinney Date: Tue, 20 Oct 2026 00:10:55 -0500 Subject: [PATCH 1/5] docs: add artifact provenance ledger (OVH-02) Add bin/PROVENANCE.md with one row per non-empty binary: size, sha256, static format, static banner, upstream version, provenance state, and the introducing commit (1fabd26, 2024-02-24). linux x64 is Anchored (byte-identical to official 24.00 7zz per V19, digest re-verified 2026-10-20); the other six rows are UNPROVEN, with the darwin row bound to gate OVH-29 and the win rows to gate OVH-07 (D-OVH-2). Placeholder slots are listed as empty and not distributed. Reconcile bin/INFO.md to the on-disk inventory: add the architecture level and .exe-or-empty extension to the layout pattern, fix the Linux example (lin/arm/x32), drop nonexistent win/arm *.exe and mac/arm/x32 paths, add the unlisted mac/pc placeholders, and name PROVENANCE.md the inventory of record. New static banner evidence (no binary executed): lin/pc/x86 24.00 (x86), lin/arm/x64 24.00 (arm64), lin/arm/x32 24.00 (armt), win/pc 7-Zip (a) 24.01 x64/x86. A Wayback availability re-check for the remaining 24.00 assets returned HTTP 429 and is recorded as such. Co-Authored-By: Claude Code --- bin/INFO.md | 52 +++++++++++++------------- bin/PROVENANCE.md | 95 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 121 insertions(+), 26 deletions(-) create mode 100644 bin/PROVENANCE.md diff --git a/bin/INFO.md b/bin/INFO.md index eaa728e..d379a51 100644 --- a/bin/INFO.md +++ b/bin/INFO.md @@ -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. \ No newline at end of file diff --git a/bin/PROVENANCE.md b/bin/PROVENANCE.md new file mode 100644 index 0000000..d6fdcdc --- /dev/null +++ b/bin/PROVENANCE.md @@ -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. From e7c6eeb5494ff2e682cc736eb0a50831838e5cf7 Mon Sep 17 00:00:00 2001 From: Micheal Kinney Date: Tue, 20 Oct 2026 00:11:05 -0500 Subject: [PATCH 2/5] docs: record Windows receipt audit gate (OVH-26) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Record audit decision D4 as a gate decision in docs/planning/: searches of the repo, git history, and GitHub issue/PR tracking found no Windows x64 or WSL qualification receipt (AGENTS.md promotion-rule format), so the plan's mandated outcome applies — uncheck claims. The README [x] Windows x64 row is marked to-uncheck (executed by OVH-04); the 0.7.3 WSL and 0.6.2 Windows-x64 changelog sentences are dispositioned as unreceipted historical claims, left unrewritten and barred from future release notes. D-OVH-2 (Windows acquisition source) explicitly remains open; the governed fallback continues. Recorded by the implementation agent under the 2026-10-20 execution directive, applying the gate's pre-stated outcome rule; the maintainer may revise or supersede it. Co-Authored-By: Claude Code --- .../DECISION_WINDOWS_RECEIPTS_2026-10-20.md | 85 +++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 docs/planning/DECISION_WINDOWS_RECEIPTS_2026-10-20.md diff --git a/docs/planning/DECISION_WINDOWS_RECEIPTS_2026-10-20.md b/docs/planning/DECISION_WINDOWS_RECEIPTS_2026-10-20.md new file mode 100644 index 0000000..d24db78 --- /dev/null +++ b/docs/planning/DECISION_WINDOWS_RECEIPTS_2026-10-20.md @@ -0,0 +1,85 @@ +# Decision record — Windows/WSL receipt audit (gate OVH-26 / audit D4) + +- **Date:** 2026-10-20 +- **Gate:** OVH-26 ("Windows/WSL receipt audit — does evidence exist for the + README's tested claims?"), consuming audit decision **D4**. +- **Owner role:** Maint. **Recorded by:** the implementation agent executing + the 2026-10-20 overhaul directive, which instructed gates that block work + to be recorded exactly rather than bypassed. The gate's outcome rule is + mandated by the plan itself ("if no receipt is found, the outcome is + 'uncheck claims', never 'assume support'", `docs/handoffs/2026-10-11-py7zip-overhaul.md` + §6 OVH-26), so this record applies that rule to the evidence below; it + invents no receipt and takes no acquisition-strategy decision. The + maintainer may revise this record at any time (rollback: docs-only + revert). +- **Receipt definition** (per `AGENTS.md` promotion rule): a recorded + qualification naming the exact commit, Python version, OS/architecture, + binary provenance, commands, and test result. + +## Question + +Do Windows x64 / WSL qualification receipts exist to back (a) the README +checklist's `[x] Windows x64 (64-bit)` row and (b) the 0.7.3 changelog +claim of testing "on Linux (Ubuntu through Windows Subsystem for Linux +(WSL))"? + +## Searches run (2026-10-20) + +| Command (abbreviated) | Outcome | +|---|---| +| `grep -rni "wsl\|windows" README.md docs/planning/PLATFORM_MATRIX.md docs/CHANGELOG.md .github/CHANGELOG.md` | Claims only, no receipts: `README.md:55` `[x] Windows x64 (64-bit)`; `docs/CHANGELOG.md:17` (0.7.3) WSL testing sentence; `docs/CHANGELOG.md:25` (0.6.2) "Tested 7za wrapper for Windows x64 platform"; `docs/planning/PLATFORM_MATRIX.md` host rows (Phase 0 historical, non-authoritative per overhaul handoff revision 4 — they record zero real-binary executions) | +| `git log --all --oneline --grep="windows\|wsl" -i` | One hit: `c86190a` (the overhaul handoff document commit itself; no receipt artifacts) | +| `gh search issues --repo aliasfoxkde/py7zip "windows receipt"` | No results | +| `gh search issues --repo aliasfoxkde/py7zip "WSL"` | One hit: issue #5, "Code In Repository Defers From Pip Package" — a bug report noting WSL reports `x86_64`; not a qualification receipt | +| GitHub issues/PR inventory, `GET /repos/aliasfoxkde/py7zip/issues?state=all` | No receipt or qualification artifacts in any issue or PR (open/closed) | +| Repository-wide file search | No receipts directory or qualification log exists anywhere under `docs/` or `.github/` | + +## Findings + +1. **No Windows x64 qualification receipt exists** in the repository, + its issue/PR history, or any recorded artifact, as of 2026-10-20. +2. **No WSL qualification receipt exists** for the 0.7.3 changelog + claim. `docs/CHANGELOG.md` is the historical release-note record for + versions that were never published to PyPI (latest PyPI release is + 0.6.2, verified 2026-10-11); its sentences are claims, not receipts, + and are left unrewritten as history. +3. `docs/planning/PLATFORM_MATRIX.md`'s Windows rows are Phase 0 + historical and record zero real-binary executions on any host; the + overhaul handoff explicitly excludes that document's host rows from + authority (revision 4, OVH-25 binding). + +## Decision (applying the plan's mandated rule) + +**No receipts found → the outcome is "uncheck claims."** + +- The README row `[x] Windows x64 (64-bit)` is marked **to-uncheck**; + OVH-04 executes this and may add no new checked row. +- The 0.7.3 WSL sentence and the 0.6.2 Windows-x64 sentence in + `docs/CHANGELOG.md` are dispositioned as **unreceipted historical + claims**: they are not rewritten (historical record), and they must + not be repeated as support claims in any future release note + (including the OVH-21 release notes and the §1 "Windows on the B0 + path" disclosure, which already requires the governed-fallback + statement). +- Audit F1 resolves to the "false claim to retract" branch: the fix is + documentation (OVH-04), executed in this tranche. + +## Scope boundaries (what this record does NOT decide) + +- **D-OVH-2 (OVH-07, Windows acquisition source) remains open.** This + record decides nothing about how Windows binaries are acquired, + bundled, or supported; the §1 governed fallback (checksum-pinned + repo-hosted binaries, UNPROVEN provenance rows, no support claim) + continues to apply until that gate is recorded. +- No macOS/Linux/other-platform row is affected by this record; other + README rows are already unchecked. +- This record creates no platform-support claim and no deprecation + window; it only reconciles claims to evidence. + +## Consequences + +- OVH-04 (platform-claim reconciliation) is unblocked and was executed + against this record in the same tranche. +- A future maintainer receipt (per the `AGENTS.md` promotion rule) may + re-check a row; that receipt supersedes this record via a docs-only + commit. From db5fe4c71cac56e36775873f12f8bf80df190a76 Mon Sep 17 00:00:00 2001 From: Micheal Kinney Date: Tue, 20 Oct 2026 00:11:13 -0500 Subject: [PATCH 3/5] docs: truth-pass USAGE, FEATURES, SETUP (OVH-03) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit USAGE.md: import line corrected to from py7zip.py7zip import Py7zip (the root package exports nothing, pinned by test_import_hygiene); example now shows the safe-runtime sequence — construct, explicit optional download_binary(), compress/decompress returning ArchiveResult — with individual-argument options (string options raise TypeError on the default runtime). FEATURES.md: the two false backup-family claims removed; full, incremental, differential, and snapshot each labeled no-op per the snapshot-family handoff Phase A per-occurrence rule (no removal version claimed, v0.8.0/v0.9.0 artifacts not described); cross- platform and "no CLI executing" claims replaced with the catalog / typed-refusal / receipts-required statement. SETUP.md: push.bat / setup.py / PYPI_API_KEY flow replaced with the actual publish.yml flow (release-triggered, tag/version gate, trusted publishing; workflow_dispatch is rehearsal only) plus locally executable test/build commands. Add tests/test_docs_truthfulness.py (4 offline tests): the Phase A per-occurrence qualifier guard, the USAGE import + construction run in a clean socket-denied interpreter, the submodule import pin, and a bar on setup.py/push.bat/PYPI_API_KEY in user-facing docs. Co-Authored-By: Claude Code --- docs/FEATURES.md | 21 ++++-- docs/SETUP.md | 67 ++++++++--------- docs/USAGE.md | 37 +++++++--- tests/test_docs_truthfulness.py | 123 ++++++++++++++++++++++++++++++++ 4 files changed, 195 insertions(+), 53 deletions(-) create mode 100644 tests/test_docs_truthfulness.py diff --git a/docs/FEATURES.md b/docs/FEATURES.md index cbb88ab..c3a9cfb 100644 --- a/docs/FEATURES.md +++ b/docs/FEATURES.md @@ -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): @@ -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) \ No newline at end of file +- Localizations for 87 languages (not currently implemented) \ No newline at end of file diff --git a/docs/SETUP.md b/docs/SETUP.md index 823ea4b..c5d929b 100644 --- a/docs/SETUP.md +++ b/docs/SETUP.md @@ -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}. diff --git a/docs/USAGE.md b/docs/USAGE.md index 6eb182c..c92507d 100644 --- a/docs/USAGE.md +++ b/docs/USAGE.md @@ -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") diff --git a/tests/test_docs_truthfulness.py b/tests/test_docs_truthfulness.py new file mode 100644 index 0000000..2060917 --- /dev/null +++ b/tests/test_docs_truthfulness.py @@ -0,0 +1,123 @@ +"""Docs guard for the OVH-03 truth-pass and Phase A of the snapshot-family +handoff. + +Pins three properties of the user-facing docs: + +1. No unqualified backup-family claim survives in ``docs/FEATURES.md`` + (the per-occurrence qualifier rule from the snapshot-family handoff: + a qualifier in one clause does not excuse an unqualified claim in + another). +2. The ``docs/USAGE.md`` import line executes in a clean interpreter + with no network access, and the constructed wrapper is the safe + runtime. +3. ``docs/USAGE.md``, ``docs/FEATURES.md``, ``docs/SETUP.md``, and + ``README.md`` never present ``setup.py`` or ``push.bat`` as the + current process. Historical changelogs are deliberately not policed: + they are records of past releases. +""" + +from __future__ import annotations + +import os +import re +import subprocess +import sys +import textwrap + +from tests.conftest import REPO_ROOT + +FEATURES = REPO_ROOT / "docs" / "FEATURES.md" +USAGE = REPO_ROOT / "docs" / "USAGE.md" +SETUP = REPO_ROOT / "docs" / "SETUP.md" +README = REPO_ROOT / "README.md" + +FAMILY = re.compile(r"\b(?:full|incremental|differential|snapshot)s?\b", re.I) +QUALIFIER = re.compile(r"\b(?:not[- ]implemented|planned|no-op)\b", re.I) +DELIMITER = re.compile("[;.]") + + +def _unqualified_family_claims(text: str) -> list[str]: + occurrences = list(FAMILY.finditer(text)) + failures = [] + for index, occurrence in enumerate(occurrences): + end = len(text) + if index + 1 < len(occurrences): + end = min(end, occurrences[index + 1].start()) + punctuation = DELIMITER.search(text, occurrence.end(), end) + if punctuation: + end = min(end, punctuation.start()) + if not QUALIFIER.search(text, occurrence.end(), end): + failures.append(occurrence.group(0)) + return failures + + +def test_features_backup_family_claims_are_all_qualified(): + text = FEATURES.read_text() + failures = _unqualified_family_claims(text) + assert failures == [], ( + "unqualified backup-family claims in docs/FEATURES.md: " + f"{failures}" + ) + + +PROBE = textwrap.dedent( + """\ + import socket + + def deny(*_args, **_kwargs): + raise AssertionError("network access during docs snippet run") + + socket.create_connection = deny + socket.getaddrinfo = deny + socket.gethostbyname = deny + socket.socket.connect = deny + socket.socket.connect_ex = deny + + from py7zip.py7zip import Py7zip + + z = Py7zip() + assert z.legacy is False + assert callable(z.compress) and callable(z.decompress) + assert callable(z.download_binary) + print("DOCS_SNIPPET_OK") + """ +) + + +def _run_docs_snippet(*, cwd): + env = dict(os.environ) + env["PYTHONDONTWRITEBYTECODE"] = "1" + env["PYTHONPATH"] = str(REPO_ROOT) + return subprocess.run( + [sys.executable, "-c", PROBE], + capture_output=True, + text=True, + cwd=str(cwd), + env=env, + timeout=180, + check=False, + ) + + +def test_usage_import_and_construction_execute_offline(tmp_path): + result = _run_docs_snippet(cwd=tmp_path) + + assert result.returncode == 0, result.stdout + result.stderr + assert "DOCS_SNIPPET_OK" in result.stdout + + +def test_usage_documents_the_submodule_import(): + text = USAGE.read_text() + assert "from py7zip.py7zip import Py7zip" in text + assert not re.search(r"^\s*import py7zip\s*$", text, re.M), ( + "docs/USAGE.md must not re-introduce the bare root import; the " + "root package defines no public API of its own" + ) + + +def test_user_docs_do_not_present_legacy_publish_flow_as_current(): + for path in (USAGE, FEATURES, SETUP, README): + text = path.read_text() + assert "push.bat" not in text, f"{path.name} references push.bat" + assert "setup.py" not in text, f"{path.name} references setup.py" + assert "PYPI_API_KEY" not in text, f"{path.name} references PYPI_API_KEY" From 1a7809c3334ceca56a43a3567ca4c9c5e42a9b0a Mon Sep 17 00:00:00 2001 From: Micheal Kinney Date: Tue, 20 Oct 2026 00:11:20 -0500 Subject: [PATCH 4/5] docs: uncheck unreceipted Windows x64 claim (OVH-04) Per the OVH-26 gate record (no Windows x64 / WSL qualification receipt found), uncheck the README's [x] Windows x64 row and note that rows may be checked only with an AGENTS.md promotion-rule receipt. Correct the install note to actual wheel behavior: the wheel ships no binaries; the default runtime acquires the artifact into ~/.cache/py7zip with sha256 verification, explicitly. Co-Authored-By: Claude Code --- README.md | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 5525f04..6125ca6 100644 --- a/README.md +++ b/README.md @@ -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. \ No newline at end of file +- 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. \ No newline at end of file From cf49becfbf4b4799b9bc2000147d6b716cdaf55c Mon Sep 17 00:00:00 2001 From: Micheal Kinney Date: Tue, 20 Oct 2026 00:11:22 -0500 Subject: [PATCH 5/5] docs: add 2026-10-20 B0 tranche progress receipt Dated receipt for this tranche (OVH-02, OVH-26, OVH-03, OVH-04): environment and device confirmation, baseline origin/main CI status, GitForge absence evidence, per-task acceptance commands and results, 133-test offline suite, clean wheel build with digest, open decision gates, and the exact next step (publication decision D3 inside OVH-21, owner-blocked; OVH-24 next unblocked implementation task). Co-Authored-By: Claude Code --- docs/planning/PROGRESS_RECEIPT_2026-10-20.md | 185 +++++++++++++++++++ 1 file changed, 185 insertions(+) create mode 100644 docs/planning/PROGRESS_RECEIPT_2026-10-20.md diff --git a/docs/planning/PROGRESS_RECEIPT_2026-10-20.md b/docs/planning/PROGRESS_RECEIPT_2026-10-20.md new file mode 100644 index 0000000..5323195 --- /dev/null +++ b/docs/planning/PROGRESS_RECEIPT_2026-10-20.md @@ -0,0 +1,185 @@ +# Progress receipt — 2026-10-20 — B0 tranche: OVH-02, OVH-26, OVH-03, OVH-04 + +Execution of `docs/handoffs/2026-10-11-py7zip-overhaul.md` (revision 4), +feature branch `agent/py7zip-overhaul-20261019`, based on `origin/main` +`a06615f` (branch and `origin/main` were identical at tranche start; +working tree clean). This receipt records what was done, the exact +commands and outcomes, and the gates that remain open. No platform +support is claimed by this receipt (`AGENTS.md` promotion rule). + +## Environment + +- Checkout: `/home/mkinney/agent-work/py7zip-quality-20261019` on + `/dev/nvme0n1p3` (btrfs, NVMe) — device confirmed before any test or + build run; work isolated in a git worktree of that checkout. +- CPython 3.14.8 (`/usr/bin/python3`), pytest 9.1.1. **Note:** 3.14 is + outside the CI test matrix (3.9–3.13); the GitHub CI run on the base + commit covers the matrix (below). No 3.9–3.13 interpreter with pytest + was available locally. +- Fedora Linux x86-64 (kernel 7.2.9). No GPU was touched; no binary in + `bin/` was executed (static `strings`/`file` probes only). + +## Baseline verification (before implementation) + +- `git fetch origin`; `origin/main` = `a06615f` = local HEAD; tree clean. +- GitHub Actions on `a06615f`: run `38230476390`, "CI" on `main`, + completed / **success**. +- Baseline suite: `unshare -rn python3 -m pytest tests -p no:cacheprovider` + → **129 passed** (offline, network namespace). +- GitForge: **not registered in this checkout** — `git remote -v` lists + only `origin` (github.com/aliasfoxkde/py7zip); `git ls-remote gitforge` + → `fatal: 'gitforge' does not appear to be a git repository`. The + canonical pipeline therefore cannot be GitForge here; GitHub Actions is + the CI surface (per U5's fallback). + +## Tasks landed (one commit each) + +### OVH-02 — Artifact provenance ledger + +- New `bin/PROVENANCE.md`: one row per non-empty binary (7 rows) with + size, sha256, static format, static banner, upstream version, + provenance state, introducing commit (`1fabd26`, 2024-02-24, for all + rows); six placeholder slots listed as empty/not distributed. +- New evidence gathered 2026-10-20 (static probes, no execution): + `bin/lin/pc/x86` banner `7-Zip (z) 24.00 (x86)`; + `bin/lin/arm/x64` banner `7-Zip (z) 24.00 (arm64)`; + `bin/lin/arm/x32` banner `7-Zip (z) 24.00 (armt)` (all 2024-01-30); + `bin/win/pc/x64` and `bin/win/pc/x86` banners `7-Zip (a) 24.01 + (x64)/(x86)` (2024-01-31) — found by broader `strings` probing; the + 2026-10-11 handoff probes had only searched for `(z)`. +- `bin/lin/pc/x64/7za` digest `12ef1251…` re-verified 2026-10-20 against + the recorded 24.00 anchor (overhaul handoff §3.1 item 12 / V19); the + archived tarball itself was not re-downloaded. +- Provenance states: linux x64 **Anchored**; the other six **UNPROVEN** + (mac row adjudicated by gate OVH-29; win rows source-decided by gate + OVH-07 / D-OVH-2). +- `bin/INFO.md` reconciled to the on-disk inventory: pattern line now + includes the architecture level and the `.exe`-or-empty extension, the + Linux example corrected to `bin/lin/arm/x32/7za`, the nonexistent + `bin/win/arm/*.exe` / `bin/mac/arm/x32/7za` paths removed, the + unlisted `bin/mac/pc/*` placeholders added, and + `bin/PROVENANCE.md` named the inventory of record. +- Acceptance run: `find bin -type f -size +0c | sort` → exactly the 7 + binaries, one ledger row each; programmatic check confirmed all 7 + catalog digests/sizes in `py7zip/platforms.py` match disk and that the + ledger covers every catalog artifact. +- Wayback availability re-check for `7z2400-linux-{x86,arm64,arm}` and + `7z2400-mac` → HTTP 429 (rate-limited), no new evidence; recorded as + such, not retried to avoid hammering the service. + +### OVH-26 — Gate: Windows/WSL receipt audit (audit D4) + +- New `docs/planning/DECISION_WINDOWS_RECEIPTS_2026-10-20.md`. +- Searches run 2026-10-20: repo greps (claims only, no receipts), + `git log --all --grep` (one hit: the handoff doc commit), + `gh search issues "windows receipt"` (0 results), `gh search issues + "WSL"` (issue #5 only — a PyPI-divergence bug report, not a receipt), + full GitHub issue/PR inventory (no receipt artifacts). +- Outcome (the plan's mandated rule, applied — no receipts found): + **uncheck claims.** README `[x] Windows x64` → to-uncheck; the 0.7.3 + WSL sentence and 0.6.2 Windows-x64 sentence in `docs/CHANGELOG.md` + are unreceipted historical claims — left unrewritten, never to be + repeated as support claims in future release notes. +- **Provenance caveat:** the gate's owner role is Maint; this record was + written by the implementation agent under the 2026-10-20 execution + directive ("if a gate is decision-blocked, record the exact decision + and work adjacent unblocked tasks without bypassing it"), applying the + gate's pre-stated outcome rule. It invents no receipt and takes no + acquisition-strategy decision (D-OVH-2 stays open). The maintainer may + revise or supersede it (docs-only revert). +- Scope boundaries honored: D-OVH-2 (OVH-07) remains open; the §1 + governed fallback (repo-hosted Windows binaries, no support claim) + continues. + +### OVH-03 — Docs truth-pass + +- `docs/USAGE.md`: example rewritten to + `from py7zip.py7zip import Py7zip` (the root package exports nothing — + pinned by `tests/test_import_hygiene.py`), the safe-runtime sequence + (construct → explicit optional `download_binary()` → compress/ + decompress returning `ArchiveResult`), individual-argument options + (string options raise `TypeError` on the default runtime), and a + factual safe-runtime note. +- `docs/FEATURES.md`: the two false claims at old lines 5–6 removed; + `full`/`incremental`/`differential`/`snapshot` each labeled no-op (per + -occurrence qualifier rule, Phase A of the snapshot-family handoff — + no removal version claimed, v0.8.0/v0.9.0 artifacts not described); + the "Cross platform support" line replaced with the catalog/ + typed-refusal statement plus the receipts requirement; the false + "removes need for … CLI executing" line corrected; "implimented" typo + fixed. +- `docs/SETUP.md`: legacy `push.bat` / `setup.py` / `PYPI_API_KEY` + publish flow replaced with the actual `.github/workflows/publish.yml` + flow (release-triggered, tag/version gate, trusted publishing, + `workflow_dispatch` = rehearsal only) and locally executable + test/build commands. +- New `tests/test_docs_truthfulness.py` (4 tests, offline): the Phase A + per-occurrence family-qualifier guard verbatim from the handoff; the + USAGE import + `Py7zip()` construction executed in a clean interpreter + subprocess with socket denial (safe runtime asserted); the submodule + import line pinned; `setup.py`/`push.bat`/`PYPI_API_KEY` barred from + USAGE/FEATURES/SETUP/README (historical changelogs deliberately not + policed). +- Acceptance runs: `grep -nF "point-in-time" docs/FEATURES.md` and + `grep -nF "Simplifies lessor known features" docs/FEATURES.md` → both + empty; the handoff's Phase A guard script → counterexample fails, + permitted wording passes, **zero findings** in `docs/FEATURES.md`; + documented commands executed (pytest, `pip wheel . --no-deps -w dist/` + → built; `pip show py7zip` runs, reports "not found" in this + non-installed environment). + +### OVH-04 — Platform-claim reconciliation + +- `README.md`: `[x] Windows x64 (64-bit)` unchecked per the OVH-26 + record; a receipts-required note added (rows may be checked only with + an `AGENTS.md` promotion-rule receipt); the install note corrected to + the actual wheel behavior (no binaries shipped; sha256-verified + acquisition into `~/.cache/py7zip`; explicit acquisition) — audit F13. +- Acceptance run: `grep -n "\[x\]" README.md` → no matches (only + receipt-backed rows remain; there are none). + +## Validation (after all edits, before commit) + +- Full offline suite: `unshare -rn python3 -m pytest tests + -p no:cacheprovider` → **133 passed** (129 baseline + 4 new docs + guards). +- Clean package build: `python3 -m pip wheel . --no-deps -w ` + → `py7zip-0.7.3-py3-none-any.whl`, 13,777 bytes, sha256 + `0b9b5b9a71db1754882fd31ec20f8a95f0e022aa75d58df05aa8fbce7b3999ff`; + 11 entries, **no `bin/`**; metadata shows `Development Status :: 4 - + Beta`, valid 3.9–3.14 classifiers, `Requires-Dist: requests` (expected + — legacy sunset is OVH-19, not this tranche). +- `python3 -c "from py7zip.py7zip import Py7zip; …"` in a clean + interpreter → constructs, `legacy is False`. +- `git diff --check` → clean. `twine` was not available locally; + `twine check` was not run (CI's package job runs it). +- Not done here, by design: no release, tag, or PyPI action; no change + to `py7zip/*.py` runtime code; no test weakened or deleted. + +## Decision gates still open (recorded, not bypassed) + +- **Publication gate (audit D3, taken inside OVH-21)** — decision- + blocked on the Maintainer: outcome (a) publish-now requires every + OVH-02 provenance row upstream-anchored or explicitly maintainer- + excepted; six rows are UNPROVEN, which forces outcome (b) (recorded + decision + dated issue) until anchored or excepted. +- **OVH-29 (D-OVH-6)** — macOS support surface + provenance; now has + its ledger row waiting (OVH-02 dependency satisfied). +- **OVH-07 (D-OVH-2)** — Windows acquisition source; bounded deadline + tied to the OVH-09 catalog freeze; governed fallback in effect. +- **OVH-06 (D-OVH-1)**, **OVH-08 (D-OVH-3)**, **OVH-20 (D-OVH-4)**, + **OVH-27 (D1)**, **OVH-28 (D2)**, **OVH-30 (D-OVH-7)** — unrecorded; + their consumers (OVH-09/10/11/13/14/17/18/19) remain gated. + +## Exact next task + +- **B0 critical path:** the next step is the **publication decision D3 + inside OVH-21**, which is owner-blocked (Maintainer). With this + tranche, every mechanical P0 task (OVH-01, 02, 03, 04, 05) is landed; + nothing further on the B0 path is unblocked until D3 — or until a + maintainer anchors/excepts the six UNPROVEN provenance rows. +- **Next unblocked, non-gated implementation task:** OVH-24 (P4, + extraction-safety policy completion; no dependencies), with OVH-22 + (P4, multi-OS CI lanes; no dependencies) as the other unblocked + option. P1 core work (OVH-09/10/11) stays blocked on the OVH-08 + decision (D-OVH-3).