aeat.application.modelo._review_package_review_only_workspace module

Review-only workspace mode for a decrypted, recipient-encrypted review package.

This module closes the “review-only workspace mode” item left open on issue #421 (2026-07-04-recipient-encryption-adr and its follow-up slices): distinct from the per-package review_only flag carried by RecipientEncryptedPackage (which only tags the sealed envelope’s disposition), this module materialises a recovered package into a typed, read-only workspace view and enforces – structurally, not by convention – that a review-only workspace can never be treated as filing authority.

A ReviewOnlyWorkspace is opened from a RecipientDecryptedPackage (the output of decrypt_review_package_for_recipient()) plus the package’s recovered ReviewPackageManifest descriptor. It is the accountant/gestor-side counterpart of local-filed-observations-are-non-official-evidence: exactly as a locally persisted filed observation must never be mistaken for official AEAT evidence, a review-only workspace must never be mistaken for a mandate to file, export, or otherwise act on the underlying revision with authority.

The guard is a hard, always-fail assertion (assert_workspace_permits_official_action()) rather than an advisory: unlike no-silent-under-declaration’s advisory-vs-blocking distinction (a legitimately ambiguous economic state), “does this workspace carry filing authority” is a closed binary fact carried on the envelope at encryption time – there is no legitimate case where a review-only workspace should be allowed to file. Any composition (a future countersign-attach-to-journal flow, a future decrypt-then-file verb) that touches a ReviewOnlyWorkspace MUST call the assertion before treating the package as filing-grade.

See also

_review_package_recipient_encryption

Produces the RecipientDecryptedPackage this module wraps, and defines the review_only disposition flag.

_review_package

Defines ReviewPackageManifest, the descriptor recovered alongside the decrypted package bytes.

exception ReviewOnlyWorkspaceError(message=None, *, context=None, suggestion=None, translated_message=None)[source]

Bases: AeatError

Base error for review-only workspace failures.

Parameters:
  • message (str | None)

  • context (Mapping[str, object] | None)

  • suggestion (str | None)

  • translated_message (str | None)

Return type:

None

code: ClassVar[ErrorCode]
exception ReviewOnlyWorkspaceAuthorityError(message=None, *, context=None, suggestion=None, translated_message=None)[source]

Bases: 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.

Parameters:
  • message (str | None)

  • context (Mapping[str, object] | None)

  • suggestion (str | None)

  • translated_message (str | None)

Return type:

None

code: ClassVar[ErrorCode]
class ReviewOnlyWorkspace(**data)[source]

Bases: 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 emit_collab_workspace_opened_event() around this constructor).

Parameters:
manifest: ReviewPackageManifest
package_bytes: bytes
review_only: bool
opened_at: datetime
property is_read_only: 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.

open_review_only_workspace(decrypted, *, manifest, opened_at=None)[source]

Materialise a decrypted package into a read-only ReviewOnlyWorkspace.

Parameters:
Return type:

ReviewOnlyWorkspace

Returns:

A ReviewOnlyWorkspace carrying the decrypted bytes, the descriptor, and the envelope’s review_only disposition.

assert_workspace_permits_official_action(workspace)[source]

Assert workspace carries filing authority; return its manifest on success.

This is the structural guard every filing/export/official-action composition over a 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.

Return type:

ReviewPackageManifest

Parameters:

workspace (ReviewOnlyWorkspace)