Archive copy must succeed before a packet counts as filed (Gitea issue 57)
ci / frontend (pull_request) Successful in 1m0s
ci / server (pull_request) Successful in 13m45s
ci / image (pull_request) Skipped
ci / e2e (pull_request) Successful in 5m49s

FILE checks the archive folder and copies the packet inside the filing
transaction. A failed check or copy rolls the filing back, so the packet
stays in its previous stage; the person filing gets 503 archive_failed,
and in its own transaction the server writes an archive.filing_blocked
audit row and raises the critical archive_failed condition to Admin for
that packet (who tried, folder, error). The next successful filing clears
it. The archive-copy job now only catches up filings made while the
archive was off. PLAN question 53, CHANGELOG, FEED and SECURITY updated.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
2026-11-03 15:52:09 -07:00
co-authored by Claude Opus 5.5
parent 5f8165c833
commit 6adaf7bf25
11 changed files with 254 additions and 98 deletions
+7 -4
View File
@@ -833,7 +833,8 @@ def apply_transition(w: Write) -> None:
def _file(w: Write) -> None:
"""FILE: the data book date, the seal, and the data book built and stored on the seal, all in this transaction.
A data book that cannot be built answers 500 databook_failed and the whole filing rolls back."""
A data book that cannot be built answers 500 databook_failed and the whole filing rolls back. So does an archive
copy that fails (archive.FilingCopyFailed, answered 503 archive_failed by the transition endpoint)."""
key = _seal_key(w)
_set_packet(w, "databook_at = now()")
row = packets.load_row(w.conn, w.id)
@@ -850,11 +851,13 @@ def _file(w: Write) -> None:
w.log_also("Data book filed", f"{pages} pages")
w.detail["seal_id"] = int(seal_id)
w.detail["databook_pages"] = pages
# The archive copy runs in the worker after this commits. A failed copy never blocks filing.
# The archive copy must succeed before the packet counts as filed (Gitea issue 57). A failure raises
# archive.FilingCopyFailed and the whole filing rolls back; the transition endpoint records it for Admin.
from . import archive
if archive.on_filed(w.conn, _settings(w), w.user_id, w.id):
w.detail["archive_requested"] = True
copied = archive.copy_at_filing(w.conn, _settings(w), w.id, int(seal_id))
if copied is not None:
w.detail["archive_folder"] = copied["folder"]
def _file_databook(w: Write, row: Mapping[str, Any], seal: dict[str, Any], seal_id: int) -> int: