Source code for aeat.application.modelo._review_package_review_only_workspace
"""Review-only workspace mode for a decrypted, recipient-encrypted review package.This module closes the "review-only *workspace* mode" item left open onissue #421 (`2026-07-04-recipient-encryption-adr` and its follow-up slices):distinct from the per-package ``review_only`` flag carried by:class:`~application.modelo.RecipientEncryptedPackage` (which only tagsthe sealed envelope's disposition), this module materialises a recoveredpackage into a typed, read-only workspace view and enforces -- structurally,not by convention -- that a review-only workspace can never be treated asfiling authority.A :class:`ReviewOnlyWorkspace` is opened from a:class:`~application.modelo.RecipientDecryptedPackage` (the output of:func:`~application.modelo.decrypt_review_package_for_recipient`) plusthe package's recovered :class:`~application.modelo.ReviewPackageManifest`descriptor. It is the accountant/gestor-side counterpart of``local-filed-observations-are-non-official-evidence``: exactly as a locallypersisted filed observation must never be mistaken for official AEATevidence, a review-only workspace must never be mistaken for a mandate tofile, export, or otherwise act on the underlying revision with authority.The guard is a hard, always-fail assertion(:func:`assert_workspace_permits_official_action`) rather than an advisory:unlike ``no-silent-under-declaration``'s advisory-vs-blocking distinction (alegitimately ambiguous economic state), "does this workspace carry filingauthority" is a closed binary fact carried on the envelope at encryptiontime -- there is no legitimate case where a review-only workspace should beallowed to file. Any composition (a future countersign-attach-to-journalflow, a future decrypt-then-file verb) that touches a:class:`ReviewOnlyWorkspace` MUST call the assertion before treating thepackage as filing-grade.See Also: :mod:`~application.modelo._review_package_recipient_encryption` Produces the :class:`~application.modelo.RecipientDecryptedPackage` this module wraps, and defines the ``review_only`` disposition flag. :mod:`~application.modelo._review_package` Defines :class:`~application.modelo.ReviewPackageManifest`, the descriptor recovered alongside the decrypted package bytes."""from__future__importannotationsfromdatetimeimportdatetimefrompydanticimportBaseModel,Fieldfrom...coreimportSTRICT_FROZEN_CONFIGas_STRICT_FROZENfrom...core.errorsimportAeatErrorfrom...core.timeimportnowas_utc_nowfrom._review_packageimportReviewPackageManifestfrom._review_package_recipient_encryptionimportRecipientDecryptedPackage
[docs]classReviewOnlyWorkspaceError(AeatError):"""Base error for review-only workspace failures."""
[docs]classReviewOnlyWorkspaceAuthorityError(ReviewOnlyWorkspaceError):"""Raised when a review-only workspace is used for an action requiring filing authority. A review-only workspace's contents may be read and verified, but MUST NEVER be treated as evidence that the underlying revision has been (or may be) filed, exported as an official artefact, or otherwise acted on with authority. This error is the structural refusal that enforces that invariant; it is never advisory. """
[docs]classReviewOnlyWorkspace(BaseModel):"""A read-only materialisation of a decrypted review package. Wraps the recovered plaintext archive bytes (``package_bytes``) and the package's descriptor (``manifest``) behind a workspace record that carries its own disposition (``review_only``) independently of, but mirroring, the envelope flag it was opened from -- so a caller that only has the workspace record (and not the original envelope) can still enforce the authority boundary without re-threading the envelope's flag through every downstream call. ``opened_at`` records when this workspace view was materialised (never persisted state by itself -- opening a workspace is a pure in-memory projection, not a write to any repository; a caller that wants an audit trail of the open composes :func:`~application.modelo.emit_collab_workspace_opened_event` around this constructor). """model_config=_STRICT_FROZENmanifest:ReviewPackageManifestpackage_bytes:bytes=Field(min_length=1)review_only:boolopened_at:datetime@propertydefis_read_only(self)->bool:"""Return ``True`` iff this workspace carries no filing authority. A workspace is read-only whenever its envelope was sealed ``review_only=True`` -- there is no separate mutable-vs-immutable toggle; the disposition is fixed at encryption time and carried verbatim through decryption and workspace materialisation. """returnself.review_only
[docs]defopen_review_only_workspace(decrypted:RecipientDecryptedPackage,*,manifest:ReviewPackageManifest,opened_at:datetime|None=None,)->ReviewOnlyWorkspace:"""Materialise a decrypted package into a read-only :class:`ReviewOnlyWorkspace`. Args: decrypted: The :class:`~application.modelo.RecipientDecryptedPackage` returned by :func:`~application.modelo.decrypt_review_package_for_recipient`. manifest: The package's recovered :class:`~application.modelo.ReviewPackageManifest` descriptor (see :func:`~application.modelo.verify_review_package` / :func:`~application.modelo.assert_review_package_verifies`, which the caller should run against the recovered archive bytes before opening a workspace, exactly as any other review-package consumer does). opened_at: Optional override for the workspace's ``opened_at`` timestamp (tests only); defaults to the current UTC time. Returns: A :class:`ReviewOnlyWorkspace` carrying the decrypted bytes, the descriptor, and the envelope's ``review_only`` disposition. """returnReviewOnlyWorkspace(manifest=manifest,package_bytes=decrypted.package_bytes,review_only=decrypted.review_only,opened_at=opened_ator_utc_now(),)
[docs]defassert_workspace_permits_official_action(workspace:ReviewOnlyWorkspace)->ReviewPackageManifest:"""Assert ``workspace`` carries filing authority; return its manifest on success. This is the structural guard every filing/export/official-action composition over a :class:`ReviewOnlyWorkspace` MUST call before treating the workspace's contents as evidence the underlying revision has been or may be filed. It is a hard refusal, never an advisory: a review-only workspace's disposition is a closed fact carried on the sealed envelope, not a judgment call with legitimate exceptions. Raises: ReviewOnlyWorkspaceAuthorityError: If ``workspace.review_only`` is ``True``. """ifworkspace.review_only:raiseReviewOnlyWorkspaceAuthorityError("review-only workspace carries no filing authority; it may be read ""and verified but must never be treated as evidence the underlying ""revision has been or will be filed",translated_message="application.modelo.errors.review_only_workspace_no_authority",context={"calculation_revision_id":workspace.manifest.calculation_revision_id,"bucket_id":workspace.manifest.bucket_id,},)returnworkspace.manifest