4.8 KiB
Independent static publication review
Reviewer: Codex-9e8r6t /root/publication_review, 2026-09-12. Root owns issue 6 and publication. Reviewed only the four files recorded in review-bindings.json; scripts were neither executed nor imported. No network, credentials, tag, release, upload, or reviewed-file mutation was performed. Files were read and hashed; this report is the only new review artifact alongside its bindings. Current remote state and final acceptance text were outside this review.
Finding requiring a controlled execution decision
P2 — Optimization removes the safety boundary. publish.py:113-124, 129-147, 152-161, 188-238 and the corresponding tag-helper checks use Python assert for input acceptance, ownership, collision detection, and remote readback. With python -O or a nonzero PYTHONOPTIMIZE, these statements disappear. For example, final files can be present while both configured hashes remain null and inputs() still returns; assert client.request(...) == raw at line 221 also removes the download itself. The mutating sequence can consequently operate without the reviewed guards. The README's unconditional claim that unbound hashes refuse before network access does not hold for optimized execution.
Recommended small fix: reject not __debug__ with an explicit if/raise at module initialization in publish.py, before any credential or network operation; the tag helper imports this module and inherits the rejection. Alternatively, root can explicitly enforce and record nonoptimized execution for every invocation, including absence of inherited PYTHONOPTIMIZE. No fix was made by this reviewer. Ordinary nonoptimized execution retains the reviewed checks.
Static conclusions
- Final notes and validation are intentionally unbound in this snapshot. Under nonoptimized execution, mutation refuses before constructing
Client; the exact pending markers are rejected, and both final texts must match independently entered SHA256 values. Semantic acceptance remains root's review responsibility. - The source branch and existing tag must resolve to exact commit
802855f7e6f2f00a107a12196b458b267f586b8d. The separate tag helper uses one explicit nonforce refspec and accepts annotated tags only at the exact peeled commit. A concurrent conflicting tag creation makes the normal push fail rather than replace it. - Release enumeration checks the reserved tag including authenticated draft listings, with a fail-closed page bound. Existing release adoption requires an explicit bound ID or the exclusive successful-create receipt; a matching tag/title alone does not authorize mutation. Final title, body, prerelease status, tag and target must match.
- Exactly three named local assets are allowed. ZIP size/hash and checksum content/hash are fixed; validation bytes are hash-bound. Existing remote assets must have unique names/IDs, expected sizes, and identical downloaded bytes. Uploads are read back; publication downloads all three before visibility change and again afterwards, comparing IDs/names/sizes/hashes/URLs. No deletion or replacement endpoint exists.
- Lost create responses require inspected manual ID adoption; successful creation persists ownership before later readback. Lost upload responses can be reconciled by fresh byte verification. Already-public publication retries repeat the checks. Attempts have exclusive directories and report uncertain remote outcomes; no automatic retry, force push or rollback occurs.
- Credentials are read from the configured connection, used in memory/request headers and a child-process environment, and not explicitly written to helper files, git config or command arguments. API origin checks and redirect refusal limit forwarding; Git redirect following is disabled and inherited
GIT_environment configuration is removed. This is a static data-flow conclusion, not dynamic fault-injection evidence. The pre-existing HTTP endpoint is unchanged. - Race limitation: draft/assets/ownership checks and later writes are separate requests, and there is no shared lock or conditional server write. A second writer could publish during the upload loop or alter assets between the prepublication check and PATCH. Root's reserved, sequential single-executor workflow is therefore a necessary operating assumption. Postchecks detect many changes but cannot promise that incorrect state was never briefly public. This is not a request for broader locking infrastructure for this one-off operation.
Readiness: structurally suitable for the coordinated one-off publication after root binds and reviews the final two files, resolves the optimization guard decision, and verifies current remote ownership/tag state. This review does not claim publication, runtime validation, current Gitea state, final-note acceptance, or asset availability.