aeat.application.modelo._review_package module¶
Review-package build and integrity verification for accountant handoff.
A review package is a shareable, checksum-verifiable ZIP archive assembled
from an already-verified or filed CalculationRevision:
the fichero-BOE draft export bytes, the revision’s typed casilla observations
(regulatory grounding included), its bundled ledger filing evidence (when
present), and a small package-info descriptor binding everything to the
source work unit / bucket / modelo / period.
This module builds and verifies review packages. It reuses the corpus-bundle
checksum-manifest primitive (build_corpus_bundle()
/ verify_corpus_bundle()) rather than
re-deriving SHA-256 bundling logic: a review package is, mechanically, a
CorpusManifest-checksummed zip whose
members happen to be filing artefacts instead of corpus reference files.
Cryptographic signing (ed25519 sender/recipient identity) and the
counter-signed accountant feedback-package round trip are explicitly OUT OF
SCOPE for this module; verify_review_package() is an INTEGRITY check
only (did every member arrive byte-for-byte as built), not an authenticity
check (who built it). A future slice adds signing and the counter-sign
receipt workflow on top of the manifest this module produces.
The package is a plaintext operator-directed handoff artefact — the operator
explicitly requested a shareable export, mirroring the existing
export() and
export_modelo_revision() plaintext-export
exceptions. Nothing here mutates encrypted bucket state or persists a new
catalogue record; the ZIP is written directly to the caller-supplied path.
See also
export_modelo_revision():Produces the fichero-BOE draft bytes bundled into the package.
LedgerFilingEvidence:The bundled ledger fact basis included when present on the revision.
build_corpus_bundle():The reused checksum-manifest zip-build primitive.
verify_corpus_bundle():The reused checksum-manifest zip-verify primitive.
- exception ReviewPackageError(message=None, *, context=None, suggestion=None, translated_message=None)[source]¶
Bases:
AeatErrorBase error for review-package build/verify failures.
- Parameters:
- Return type:
None
- code: ClassVar[ErrorCode]¶
- exception ReviewPackageRevisionStateError(message=None, *, context=None, suggestion=None, translated_message=None)[source]¶
Bases:
ReviewPackageErrorRaised when the source revision is not eligible for a review package.
Eligible states are
VERIFICADO_COMPLETOandPRESENTADO(see_ELIGIBLE_REVISION_STATES): a review package shares a filing-grade figure with an accountant, so a bare draft or a superseded revision is refused before any bytes are written.- Parameters:
- Return type:
None
- code: ClassVar[ErrorCode]¶
- exception ReviewPackageIntegrityError(message=None, *, context=None, suggestion=None, translated_message=None)[source]¶
Bases:
ReviewPackageErrorRaised when a review package fails checksum-manifest verification.
Wraps the underlying
CorpusBundleErrorfamily (missing/unexpected/mismatched members, manifest tamper, or a structurally invalid archive) behind one review-package-scoped error so callers do not need to import the corpus-manifest error hierarchy.- Parameters:
- Return type:
None
- code: ClassVar[ErrorCode]¶
- class ReviewPackageManifest(**data)[source]¶
Bases:
BaseModelPackage-info descriptor embedded in every review package as JSON.
Distinct from the reused
CorpusManifest(which only knows file names, sizes, and digests): this descriptor carries the review-domain identity — which work unit, calculation revision, bucket, modelo, and period the package represents — so a receiving side can address the package without re-parsing the fichero bytes.- Parameters:
package_info_version (int)
bucket_id (Annotated[str, StringConstraints(strip_whitespace=True, to_upper=None, to_lower=None, strict=None, min_length=1, max_length=128, pattern=None, ascii_only=None)])
work_unit_id (Annotated[str, StringConstraints(strip_whitespace=True, to_upper=None, to_lower=None, strict=None, min_length=64, max_length=64, pattern=^[0-9a-f]{64}$, ascii_only=None)])
calculation_revision_id (Annotated[str, StringConstraints(strip_whitespace=True, to_upper=None, to_lower=None, strict=None, min_length=64, max_length=64, pattern=^[0-9a-f]{64}$, ascii_only=None)])
modelo (str)
filing_year (int)
period (Period)
revision_state (str)
has_ledger_evidence (bool)
built_at (datetime)
built_by (str)
notes (str)
- package_info_version: int¶
- bucket_id: BucketId¶
- work_unit_id: WorkUnitId¶
- calculation_revision_id: CalculationRevisionId¶
- modelo: str¶
- filing_year: int¶
- period: Period¶
- revision_state: str¶
- has_ledger_evidence: bool¶
- built_at: datetime¶
- built_by: str¶
- notes: str¶
- class ReviewPackageBuildResult(**data)[source]¶
Bases:
BaseModelReceipt produced by
build_review_package().- Parameters:
output_path (Path)
manifest (ReviewPackageManifest)
corpus_root_name (str)
member_count (int)
- output_path: Path¶
- manifest: ReviewPackageManifest¶
- corpus_root_name: str¶
- member_count: int¶
- class ReviewPackageVerification(**data)[source]¶
Bases:
BaseModelOutcome of
verify_review_package().missing/unexpected/mismatchedmirrorCorpusBundleVerificationexactly (the review package’s checksum layer IS a corpus bundle);manifestis the review-specificReviewPackageManifestrecovered from the package’spackage-info.jsonmember once the archive is confirmed clean enough to read it.- Parameters:
- manifest: ReviewPackageManifest¶
- missing: tuple[str, ...]¶
- unexpected: tuple[str, ...]¶
- mismatched: tuple[str, ...]¶
- build_review_package(*, revision, work_unit, draft_bytes, output_path, built_by, notes='', generated_at=None)[source]¶
Assemble a shareable, checksum-verifiable review package ZIP.
revisionmust be in a filing-grade state (VERIFICADO_COMPLETOorPRESENTADO); see_ELIGIBLE_REVISION_STATES.work_unitis the revision’s parent (carriesbucket_id/modelo/filing_year/period, whichCalculationRevisionitself does not store); the caller must confirmwork_unit.work_unit_id == revision.work_unit_idbefore calling — this function trusts that binding rather than re-resolving it, keeping this module free of a catalogue-repository dependency.draft_bytesis the already-rendered fichero-BOE artefact (the caller obtains this fromexport_modelo_revision(), which owns every export-time safety gate — evidence completeness, cross-period clean state, IVA wallet reconciliation — so this function does not re-validate export eligibility beyond the revision-state check above).The package bundles four members under a checksum manifest built by
build_corpus_bundle()(reused verbatim, not re-derived):draft.fichero-boe— the rendered filing artefact bytes.revision.json— the fullCalculationRevision, including its typedobservations(legal_refs / source_refs grounding for every casilla).evidence.json— the revision’s bundledLedgerFilingEvidencewhen present, or an explicit{"present": false}marker when the revision carries no ledger evidence (a non-ledger modelo, or a manual-only filing).package-info.json— theReviewPackageManifestdescriptor.
Members are written to a temporary staging directory then packed with
build_corpus_bundle(), which itself writes atomically (temp-file-then-rename) so a build failure never leaves a partial package atoutput_path.- Raises:
ReviewPackageRevisionStateError – If
revision.stateis not in_ELIGIBLE_REVISION_STATES.ReviewPackageError – If
work_unit.work_unit_iddoes not matchrevision.work_unit_id.
- Return type:
- Parameters:
- verify_review_package(package_path)[source]¶
Verify a review package’s checksum manifest and recover its descriptor.
Delegates the checksum layer entirely to
verify_corpus_bundle()(no hashing logic is re-derived here). When the archive is clean, the embeddedpackage-info.jsonmember is loaded and validated into aReviewPackageManifest. A dirty archive still returns a best-effort manifest recovery whenpackage-info.jsonitself matches its checksum record (so the caller can report WHICH package failed even when some other member is missing or mismatched); if the descriptor itself cannot be recovered, verification fails loudly rather than fabricating a manifest.This is an INTEGRITY check only: it confirms every archived member matches the manifest byte-for-byte. It makes no claim about WHO built the package (that is the deferred cryptographic-signing slice).
- Raises:
FileNotFoundError – If
package_pathdoes not exist.ReviewPackageIntegrityError – If the archive is not a valid zip, the embedded corpus manifest is absent/structurally invalid/tampered, or the
package-info.jsonmember cannot be recovered.
- Return type:
- Parameters:
package_path (Path)
- assert_review_package_verifies(package_path)[source]¶
Verify
package_pathand raise on any drift; return its descriptor on success.Mirrors
assert_corpus_bundle_verifies()for the review-package surface: the operator-facing assertion a receiving side calls before trusting a handed-over package.- Return type:
- Parameters:
package_path (Path)