aeat.domain.calculations.registry._groi_oracle module¶
AEAT GROI Spanish-ROI consult oracle.
The GROI servlet at www2.agenciatributaria.gob.es certifies whether
a given Spanish NIF is registered in the AEAT Registro de Operadores
Intracomunitarios. Live probing on 2026-05-07 confirmed the surface
is reachable under cl@ve-movil authentication; the live driver lives
at aeat.adapters.outbound.aeat.sede._groi_check and this module
wraps it as a LiveParityOracle.
The oracle is the SPANISH-counterparty sibling of
_aeat_nif_iva_oracle (foreign-EU VIES proxy). Both share the
iva_id_check surface kind and pair with cross-references whose
surface is public_read_surface; the registry’s surface-kind
compatibility table at _live_parity._COMPATIBLE_SURFACE_PAIRS
already declares that pair.
READ-ONLY MANDATE¶
AEAT writes are PERMANENTLY FORBIDDEN. The GROI form’s submit handler
is an HTTP POST to ConsultaOperadorSedeGroiServlet — but per AEAT
service contract this POST is a CONSULT (a SELECT against the ROI
registry) and modifies no AEAT-side state. The submitting NIF is not
recorded against the queried NIF, no draft is created, no filing
history entry is generated. Every observation captured during live
probing 2026-05-07 confirmed the form’s only side effect is rendering
a verdict page back to the caller.
Defense-in-depth nonetheless: the registry’s RemoteStateGuard
fence intercepts every operation the oracle emits BEFORE any browser
action runs. Any guard policy attached to a GROI cross-reference MUST
declare forbidden_actions containing the canonical
AEAT_WRITE_FORBIDDEN_ACTIONS set so that, were a future driver
refactor to mislabel an operation (or were AEAT to silently change the
endpoint to a state-modifying action), the guard rejects the
operation BEFORE it leaves the process. The unit and live tests
exercise the guard with deliberately fabricated write operations to
prove the read-only invariant by construction.
- class GroiObservation(**data)[source]¶
Bases:
_CheckerBaseModelObserved Spanish-ROI verdicts returned by an executable adapter.
valueskeys are upper-cased Spanish NIFs;valuesvalues are lowercase verdict tokens (valid/invalid/unknown).- values: dict[str, str]¶
- raw_evidence_locator: str | None¶
- class GroiDriver(*args, **kwargs)[source]¶
Bases:
ProtocolExecution boundary for GROI live or replay adapters.
- property mode: Literal['live', 'replay']¶
Discriminate which execution surface this driver speaks to.
Returns either
"live"(a driver that drives the real AEAT GROI servlet through an authenticated browser session) or"replay"(a driver that decodes a previously captured response from local corpus bytes).GroiOraclereads this to label evidence provenance and to decide whether a run touched the network.- Returns:
The literal
"live"or"replay".
- planned_operations(payload, *, expected)[source]¶
Declare the remote operations this driver intends to perform.
The operations are pre-flighted through the registry’s remote-state guard before any of them runs, so the read-only invariant can be enforced by construction. The driver returns the sequence it would execute for the given probe rather than executing it.
- Parameters:
payload (
bytes) – Raw adapter input bytes (a live request envelope or a captured replay document, depending on the driver mode).expected (
Mapping[str,object]) – Mapping of Spanish NIF (the per-taxpayer fiscal identifier) to its expected ROI-registration verdict; ROI is the AEAT Registro de Operadores Intracomunitarios, the register of operators cleared for intra-EU trade.
- Return type:
- Returns:
The ordered
RemoteOperationtuple this driver would emit.
- collect_observation(payload, *, expected)[source]¶
Execute the GROI probe and return the observed verdicts.
- Parameters:
- Return type:
- Returns:
A
GroiObservationwhosevaluesmap upper-cased NIFs to lowercase verdict tokens (valid/invalid/unknown).
- class GroiReplayDriver[source]¶
Bases:
objectDeterministic local replay driver for captured GROI outputs.
Payload shape:
{ "observed": {"A28015865": "valid", "B12345678": "invalid"}, "raw_evidence_locator": "corpus/aeat_official/groi_response_samples/..." }
- property mode: Literal['replay']¶
Identify this driver as a deterministic local replay.
Always
"replay": this driver decodes a captured GROI response from local corpus bytes and never touches the network, making it the offline counterpart used by the parity test suite.- Returns:
The literal
"replay".
- planned_operations(payload, *, expected)[source]¶
Declare the single local-parse operation a replay performs.
Both arguments are ignored: a replay reads a fixed captured document and performs no network or browser action, so it returns exactly one
RemoteOperationof kindlocal_workbookwith actionparse-groi-replay. The remote-state guard still pre-flights this list for uniformity with the live path.- Parameters:
- Return type:
- Returns:
A one-element tuple naming the local replay-parse
RemoteOperation.
- collect_observation(payload, *, expected)[source]¶
Decode the captured replay payload into observed verdicts.
The
expectedmapping is ignored; the observation is read straight from the captured document. The payload is a JSON envelope with anobservedobject (NIF to verdict) and an optionalraw_evidence_locatorpointing at the corpus sample on disk.- Parameters:
- Return type:
- Returns:
A
GroiObservationcarrying the captured verdicts and evidence locator.- Raises:
RegistryValidationError – If the payload is malformed or carries blank NIF keys or verdict values.
- class GroiOracle(*, driver=None)[source]¶
Bases:
BaseCheckerOracle[GroiObservation]AEAT-mediated Spanish-ROI registration validator.
Wraps a
GroiDriver(live or replay). When no driver is configured the oracle still pre-flights the planned operations through the remote-state guard;verify_payloadthen returnsunverifiablebecause no observation was available for comparison. With a driver configured the oracle compares the expected verdict per NIF against the driver-emitted observation and returnsmatch/mismatchaccordingly.- Parameters:
driver (GroiDriver | None)
- surface_label: str¶
- property oracle_id: OracleId¶
Return the stable catalogue identifier for this oracle.
The value is the module-level
GROI_ORACLE_IDconstant (aeat-groi-spanish-roi-checker), used as the key under which the oracle registers in the live-parity catalogue.- Returns:
The catalogue registration key.
- property surface_kind: Literal['file_validator', 'open_simulator', 'iva_id_check', 'pre_filing_validator', 'integration_test_service']¶
Return the surface-kind tag that gates cross-reference pairing.
Always
"iva_id_check": the same tag carried by the VIES sibling oracle. VIES (VAT Information Exchange System) is the EU service that checks foreign-EU VAT identifiers, the GROI equivalent for the rest of the EU. Sharing the tag lets the registry’s surface-kind compatibility table pair GROI checks againstpublic_read_surfacecross-references (other read-only public lookups).- Returns:
The
OracleSurfaceKindliteral"iva_id_check".
- planned_operations(payload, *, expected)[source]¶
Declare the remote operations a GROI verification would perform.
The operations are pre-flighted through the remote-state guard before any browser action runs, enforcing the read-only AEAT mandate by construction. With a driver configured the call delegates to that driver. With no driver configured the oracle synthesises the canonical live sequence directly: a GET against the GROI servlet URL pulled from central config, a browser action to open the form, one
check-nif-<nif>action per expected NIF in sorted order, and a finaldiscard-sessionaction.- Parameters:
- Return type:
- Returns:
The ordered
RemoteOperationtuple for this verification.- Raises:
RegistryValidationError – If
expectedis empty, or if any NIF key or verdict value is blank.
- register_default(catalogue, *, environment=OracleEnvironment.PRODUCTION)[source]¶
Register the GROI Spanish-ROI oracle under the requested environment.
- Return type:
- Parameters:
catalogue (LiveParityCatalogue)
environment (OracleEnvironment)